该程序与线程如何工作?

时间:2019-04-17 10:04:57

标签: c multithreading pthreads

我尝试学习有关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;
}

4 个答案:

答案 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;
}