pthread 的奇怪行为
Strange Behavior with pthreads
我有一个相当奇怪的问题,尽管在我正在启动的线程中锁定了关键代码部分,但我没有得到正确的结果 -
#include <stdio.h>
#include <pthread.h>
#include <thread>
#include <mutex>
#define NUMTAGS 6
std::mutex foo,bar;
pthread_mutex_t mutex;
typedef struct PKT{
int ii;
int jj;
}pkt;
void *print(void *pk)
{
pthread_mutex_lock(&mutex);
pkt *x = (pkt *)pk;
printf("--> %d %d %d\n", x->ii, x->jj, x->ii*NUMTAGS + x->jj);
pthread_mutex_unlock(&mutex);
}
int main(int argc, char **argv)
{
int count = 3;
int ii, jj;
pthread_t t_id[count*NUMTAGS];
int t_status[count*NUMTAGS];
pkt p;
pkt *p_p = &p;
for(ii=0; ii < count; ii+=1){
for(jj=0; jj < NUMTAGS; jj+=1){
p.ii = ii;
p.jj = jj;
//printf("<> %d %d %d\n", p_p->ii, p_p->jj, p_p->ii*NUMTAGS + p_p->jj);
t_status[ii*NUMTAGS + jj]=pthread_create(&t_id[ii*NUMTAGS + jj], NULL, print, (void*)p_p);
}
}
for(ii=0; ii < count; ii+=1){
for(jj=0; jj < NUMTAGS; jj+=1){
pthread_join(t_id[ii*NUMTAGS + jj], NULL);
}
}
}
结果答案随机错误...
--> 0 3 3
--> 1 0 6
--> 1 0 6
--> 1 0 6
--> 1 0 6
--> 1 0 6
--> 1 1 7
--> 1 2 8
--> 1 3 9
--> 1 5 11
--> 2 0 12
--> 2 0 12
--> 2 1 13
--> 2 3 15
--> 2 4 16
--> 2 5 17
--> 2 5 17
--> 2 5 17
谁能告诉我启动打印线程并让正文自动执行的正确方法是什么?
谢谢,
拉吉
您有两个问题:
首先,执行main
的线程修改p.ii
和p.jj
而不持有互斥量。因此,当您创建的线程读取 ii
和 jj
时,任何事情都可能发生,因为它们可能正在被修改。
其次,不清楚您期望的行为和原因。您看到的输出是完全合理的。你说这是“错误的”,但不解释为什么它是错误的。您不强制在线程 运行ning main
和打印线程之间进行任何排序。线程 运行ning main
可能会设法更改 ii
和 jj
几次,然后才能创建线程 运行.
为什么你认为两个线程打印相同的东西是“错误的”?你认为是什么迫使第一个线程在 main
线程多次修改 ii
和 jj
之前完成?
谢谢大卫,
在您发表评论后,我修改了我的代码,现在可以使用了 -
#include <stdio.h>
#include <pthread.h>
#include <thread>
#include <mutex>
#define NUMTAGS 6
std::mutex foo,bar;
pthread_mutex_t mutex;
typedef struct PKT{
int ii;
int jj;
}pkt;
void *print(void *pk)
{
pthread_mutex_lock(&mutex);
pkt *x = (pkt *)pk;
printf("--> %d %d %d\n", x->ii, x->jj, x->ii*NUMTAGS + x->jj);
pthread_mutex_unlock(&mutex);
}
int main(int argc, char **argv)
{
int count = 3;
int ii, jj;
pthread_t t_id[count*NUMTAGS];
int t_status[count*NUMTAGS];
pkt p[count*NUMTAGS];
pkt *p_p = p;
/*pre-assigned structure before launching thread*/
for(ii=0; ii < count; ii+=1){
for(jj=0; jj < NUMTAGS; jj+=1){
p[NUMTAGS*ii + jj].ii= ii;
p[NUMTAGS*ii + jj].jj= jj;
}
}
for(ii=0; ii < count; ii+=1){
/*assign p_p[i] to thread i*/
for(jj=0; jj < NUMTAGS; jj+=1, p_p+=1){
//printf("<> %d %d %d\n", p_p->ii, p_p->jj, p_p->ii*NUMTAGS + p_p->jj);
t_status[ii*NUMTAGS + jj]=pthread_create(&t_id[ii*NUMTAGS + jj], NULL, print, (void*)p_p);
}
}
for(ii=0; ii < count; ii+=1){
for(jj=0; jj < NUMTAGS; jj+=1){
pthread_join(t_id[ii*NUMTAGS + jj], NULL);
}
}
}
我有一个相当奇怪的问题,尽管在我正在启动的线程中锁定了关键代码部分,但我没有得到正确的结果 -
#include <stdio.h>
#include <pthread.h>
#include <thread>
#include <mutex>
#define NUMTAGS 6
std::mutex foo,bar;
pthread_mutex_t mutex;
typedef struct PKT{
int ii;
int jj;
}pkt;
void *print(void *pk)
{
pthread_mutex_lock(&mutex);
pkt *x = (pkt *)pk;
printf("--> %d %d %d\n", x->ii, x->jj, x->ii*NUMTAGS + x->jj);
pthread_mutex_unlock(&mutex);
}
int main(int argc, char **argv)
{
int count = 3;
int ii, jj;
pthread_t t_id[count*NUMTAGS];
int t_status[count*NUMTAGS];
pkt p;
pkt *p_p = &p;
for(ii=0; ii < count; ii+=1){
for(jj=0; jj < NUMTAGS; jj+=1){
p.ii = ii;
p.jj = jj;
//printf("<> %d %d %d\n", p_p->ii, p_p->jj, p_p->ii*NUMTAGS + p_p->jj);
t_status[ii*NUMTAGS + jj]=pthread_create(&t_id[ii*NUMTAGS + jj], NULL, print, (void*)p_p);
}
}
for(ii=0; ii < count; ii+=1){
for(jj=0; jj < NUMTAGS; jj+=1){
pthread_join(t_id[ii*NUMTAGS + jj], NULL);
}
}
}
结果答案随机错误...
--> 0 3 3
--> 1 0 6
--> 1 0 6
--> 1 0 6
--> 1 0 6
--> 1 0 6
--> 1 1 7
--> 1 2 8
--> 1 3 9
--> 1 5 11
--> 2 0 12
--> 2 0 12
--> 2 1 13
--> 2 3 15
--> 2 4 16
--> 2 5 17
--> 2 5 17
--> 2 5 17
谁能告诉我启动打印线程并让正文自动执行的正确方法是什么?
谢谢, 拉吉
您有两个问题:
首先,执行main
的线程修改p.ii
和p.jj
而不持有互斥量。因此,当您创建的线程读取 ii
和 jj
时,任何事情都可能发生,因为它们可能正在被修改。
其次,不清楚您期望的行为和原因。您看到的输出是完全合理的。你说这是“错误的”,但不解释为什么它是错误的。您不强制在线程 运行ning main
和打印线程之间进行任何排序。线程 运行ning main
可能会设法更改 ii
和 jj
几次,然后才能创建线程 运行.
为什么你认为两个线程打印相同的东西是“错误的”?你认为是什么迫使第一个线程在 main
线程多次修改 ii
和 jj
之前完成?
谢谢大卫, 在您发表评论后,我修改了我的代码,现在可以使用了 -
#include <stdio.h>
#include <pthread.h>
#include <thread>
#include <mutex>
#define NUMTAGS 6
std::mutex foo,bar;
pthread_mutex_t mutex;
typedef struct PKT{
int ii;
int jj;
}pkt;
void *print(void *pk)
{
pthread_mutex_lock(&mutex);
pkt *x = (pkt *)pk;
printf("--> %d %d %d\n", x->ii, x->jj, x->ii*NUMTAGS + x->jj);
pthread_mutex_unlock(&mutex);
}
int main(int argc, char **argv)
{
int count = 3;
int ii, jj;
pthread_t t_id[count*NUMTAGS];
int t_status[count*NUMTAGS];
pkt p[count*NUMTAGS];
pkt *p_p = p;
/*pre-assigned structure before launching thread*/
for(ii=0; ii < count; ii+=1){
for(jj=0; jj < NUMTAGS; jj+=1){
p[NUMTAGS*ii + jj].ii= ii;
p[NUMTAGS*ii + jj].jj= jj;
}
}
for(ii=0; ii < count; ii+=1){
/*assign p_p[i] to thread i*/
for(jj=0; jj < NUMTAGS; jj+=1, p_p+=1){
//printf("<> %d %d %d\n", p_p->ii, p_p->jj, p_p->ii*NUMTAGS + p_p->jj);
t_status[ii*NUMTAGS + jj]=pthread_create(&t_id[ii*NUMTAGS + jj], NULL, print, (void*)p_p);
}
}
for(ii=0; ii < count; ii+=1){
for(jj=0; jj < NUMTAGS; jj+=1){
pthread_join(t_id[ii*NUMTAGS + jj], NULL);
}
}
}