我尝试学习有关c语言中线程编程的基础知识。我发现了一些我无法解决的问题。 程序写五次五(为什么只有五个?为什么不1,2,3或4) 和当我注释line sleep(5)和不注释时有什么区别?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *dretva (void *x)
{
sleep(2);
printf("%d\n", *((int *)x));
return NULL;
}
int main()
{
pthread_t id[5];
int i;
for(i=0;i<5;i++)
{
pthread_create(&id[i], NULL, dretva, (void*)&i);
}
sleep(5); // why is different when this line is commented?
return 0;
}
答案 0 :(得分:3)
在这种情况下,由于不能保证线程的运行顺序,因此无法准确预测输出。并且由于每个线程中的sleep
,在这种情况下,i
的值已经在5
中增加到for
在第一个线程执行之前循环。
如果要按升序查看i
的输出,只需在pthread_join
循环中调用for
。
for(i=0;i<5;i++)
{
pthread_create(&id[i], NULL, dretva, (void*)&i);
pthread_join(id[i], NULL);
}
请参见Demo
答案 1 :(得分:1)
程序写五次五(为什么只写五个?为什么不写1,2,3或4)
所有线程开始执行时,主线程中i
的值已经设置为5。但是不能保证总是打印5次5次。无论执行线程时i的值是多少,该值都会被打印出来。
我在注释行sleep(5)时有什么区别
此代码的开发人员正在使主线程等待5秒。您应该使用join阻塞主线程,直到其他线程返回为止。
答案 2 :(得分:1)
您可能在这里面临比赛条件。关键是,正如Naveen Kumar指出的那样,当线程变为活动状态时,i地址的内容为5,因此,每个线程都打印出在i地址中找到的内容。 如果您选择提供该值,则应获得期望的结果。 使用sleep语句,您会将主线程发送到后台,使内容保持在i地址不变。没有此语句,您的主线程将终止,从而释放地址i的内存。因此,您的线程可能会发现要打印的随机数。如果要避免这种情况,请尝试熟悉pthread_join。
答案 3 :(得分:0)
您正在传递i的地址作为参数。循环结束后,i的值为5。所有线程睡眠2秒钟并打印相同的值。
(void *)&i
pthread_create(&id[i], NULL, dretva, (void*)&i);
您可以使用数组存储提示。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *dretva (void *x)
{
sleep(2);
printf("%d\n", *((int *)x));
return NULL;
}
int main()
{
pthread_t id[5];
int args[5];
int i;
for(i=0;i<5;i++)
{ int j;
args[i] = i; // storing tid
pthread_create(&id[i], NULL, dretva, &args[i]);
}
sleep(5);
return 0;
}