我是这些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。帮助
答案 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);
要考虑的其他事项:
toSync
需要对ID为0的线程进行特殊处理,因为它没有任何等待的前任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;
}