pthreads没有串行执行

时间:2012-08-11 16:17:44

标签: c synchronization pthreads

我是这些pthreads的新手。我编写了一个程序,以便不是随机显示数字,而是应该按顺序显示。我已经使用了 pthrea_join()方法。该计划如下:

int cnt=0,i=1;
pthread_t th[10];
int printmsg()
{
  cnt++;
  printf( "thread no. %d\n",cnt);
}
void tosync()
{
  if(i>0)
  pthread_join(th[i-1],NULL); // <---here i am blocking the previous thread..                         
  printmsg();
}
void main(void)
{
  pthread_create(&th[0], NULL,(void*)&tosync, NULL);
  for( i=1;i<10; i++){
    pthread_create(&th[i],NULL, (void*) &tosync, NULL);
  } 
  int y;
  for(int i=0; i<10; i++)
    pthread_join(th[i],NULL);
  return;
}

我仍在随机获取数字...... plzz。帮助

5 个答案:

答案 0 :(得分:2)

您应该将某些内容传递到tosync例程中,以便每个线程都知道它应该等待哪个线程。此外,第一个线程不应该等待任何人。如果为线程启动例程使用正确的签名,则可以传入参数。

void * tosync(void *arg)
{
  pthread_t *me = (pthread_t *)arg;
  if (me > th) pthread_join(me[-1],NULL);
  printmsg();
  return 0;
}

main应该返回int。它的循环现在已经简化,因为启动例程不再需要强制转换。由于每个线程已经与其前一个线程连接,因此main线程只需要与最后一个线程连接。

int main(void)
{
  for( i=0;i<10; i++){
    pthread_create(&th[i],NULL, tosync, &th[i]);
  }
  pthread_join(th[9],NULL);
  return 0;
}

答案 1 :(得分:1)

pthread_join(th [i-1],NULL)这一行有一些问题。当你创建一个线程时,你增加了i的值。假设 创建前三个线程OS切换thrid线程启动和OS切换到主线程,它创建其余的线程。创建所有线程后,i的值为10 / 现在假设OS切换到thrid线程然后他等待10-1 = 9th线程完成并且类似地继续。所以最终它总是随机打印。你的策略是错误的。

试试这个

int cnt=0,i=1;
pthread_t th[10];
int printmsg()
{
cnt++;
printf( thread no. %d\n",cnt);
}
void tosync()
{

printmsg();
}
void main(void)
{
pthread_create(&th[0], NULL,(void*)&tosync, NULL);
for( i=1;i<10; i++){
pthread_create(&th[i],NULL, (void*) &tosync, NULL);
pthread_join(th[i],NULL); // <---here i am blocking the previous thread..   
} 

return;
}

答案 2 :(得分:1)

在使用toSync值的i函数中,问题是当运行toSync函数时,您不知道i具有什么值。

在极端情况下,它可以为所有线程赋值10,如果创建线程的循环在任何创建的线程可以运行之前运行,就会发生这种情况。

干净的解决方案是将i值作为参数传递给pthread_create,让toSync使用该值代替全局i。 E.g。

int *id = (int*)malloc(sizeof(int));
*id = i;
pthread_create(&th[i],NULL, (void*) &tosync, id);

要考虑的其他事项:

  1. toSync需要对ID为0的线程进行特殊处理,因为它没有任何等待的前任
  2. main中的最后一个循环不应该在线程0-8上调用pthread_join,因为它们已经加入。在同一个帖子上多次调用pthread_join的结果是undefined

答案 3 :(得分:1)

正在发生的事情是,tosync()方法使用全局变量i,而不是在线程实际启动时知道i的值。如果你想将i(或这里指向前一个pthread_t的指针)传递给tosync,以便它实际记住它应该加入哪个线程,你需要通过pthread_create传递它,比如;

void* tosync(void* ptr)
{
  pthread_t* threadIndex = (pthread_t*)ptr;
  if(threadIndex != NULL)
      pthread_join(*threadIndex, NULL); // <---here i am blocking the previous thread..                         
  printmsg();
}

...in the loop...

pthread_create(&th[i], NULL, tosync, &th[i-1]);

这是pthread_create的最后一个参数,它将作为方法中的threadIndex传入,如果它包含索引,则每个线程都知道它的单独索引。

答案 4 :(得分:1)

另一种方法:

#include <stdio.h>
#include <pthread.h>

struct threadData{
    int id;
    pthread_t prev;
};


void tosync(void *data)
{
    struct threadData *td=data;
    if ((*td).prev!=0){
        printf("%i waiting\n",(*td).id);
        fflush(0);
        pthread_join((*td).prev,NULL); // <---here i am blocking the previous thread..                         
    }
    printf("%i runnning\n",(*td).id);
    fflush(0);
    free(td);
}

int main(void)
{
    int i;
    struct threadData *td;
    pthread_t nextThreadID=0;
    for( i=0;i<10; i++){
        td=malloc(sizeof(struct threadData));
        (*td).prev=nextThreadID;
        (*td).id=i;
        pthread_create(&nextThreadID,NULL, (void*) &tosync, (void *)td);
    } 
    pthread_join(nextThreadID,NULL);
    return 0;
}