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.iip.jj而不持有互斥量。因此,当您创建的线程读取 iijj 时,任何事情都可能发生,因为它们可能正在被修改。

其次,不清楚您期望的行为和原因。您看到的输出是完全合理的。你说这是“错误的”,但不解释为什么它是错误的。您不强制在线程 运行ning main 和打印线程之间进行任何排序。线程 运行ning main 可能会设法更改 iijj 几次,然后才能创建线程 运行.

为什么你认为两个线程打印相同的东西是“错误的”?你认为是什么迫使第一个线程在 main 线程多次修改 iijj 之前完成?

谢谢大卫, 在您发表评论后,我修改了我的代码,现在可以使用了 -

#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);
    }
  }
 
}