1

我是这些 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。帮助

4

5 回答 5

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;
}
于 2012-08-11T18:28:17.540 回答
1

pthread_join(th[i-1],NULL) 这一行有一些问题。当你创建一个线程时,你会创建 i 的值。假设创建前三个线程操作系统切换第三线程启动和操作系统切换到它创建其余线程的主线程。创建所有线程后,i 的值为 10/ 现在假设操作系统切换到第三线程,然后他等待 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;
}
于 2012-08-11T17:59:41.777 回答
1

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

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

干净的解决方案是将i值作为参数传递给pthread_create并让toSync使用它而不是 global i。例如

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

其他需要考虑的事情:

  1. toSync需要对 id 为 0 的线程进行特殊处理,因为它没有任何前任等待
  2. 最后一个循环main不应pthread_join在线程 0-8 上调用,因为它们已经加入。pthread_join在同一个线程上多次调用的结果是未定义的
于 2012-08-11T18:06:17.647 回答
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 传递,如果它包含索引,则每个线程都将知道其单独的索引。

于 2012-08-11T18:08:03.107 回答
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;
}
于 2012-08-11T18:17:32.063 回答