我对线程和分叉比较新。所以为了更好地理解它们,我一直在编写简单的程序。其中一个小程序我编写了两个程序,一个用于打印两个进程的计数器,另一个用两个线程打印。 我注意到的是,当线程打印一个线程的计数器然后是其他线程时,fork打印交错的计数器。所以线程不是那么平行,但行为更串行为什么呢?难道我做错了什么?
另外,pthread_join到底做了什么?即使我不做pthread_join,程序运行也类似。
这是我的线程代码
void * thread1(void *a){
int i =0;
for(i=0; i<100; i++)
printf("Thread 1 %d\n",i);
}
void * thread2(void *b){
int i =0;
for(i=0; i<100; i++)
printf("Thread 2 %d\n", i);
}
int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,thread1, NULL);
pthread_create(&tid2,NULL,thread2, NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
这是我的fork代码
int main(void)
{
pid_t childPID;
childPID = fork();
if(childPID >= 0) // fork was successful
{
if(childPID == 0) // child process
{ int i;
for(i=0; i<100;i++)
printf("\n Child Process Counter : %d\n",i);
}
else //Parent process
{
int i;
for(i=0; i<100;i++)
printf("\n Parent Process Counter : %d\n",i);
}
}
else // fork failed
{
printf("\n Fork failed, quitting!!!!!!\n");
return 1;
}
return 0;
}
编辑: 如何使线程程序更像fork程序?即计数器打印交织。
答案 0 :(得分:1)
你正走在一条糟糕的道路上。您应该学习的教训是不要试图考虑操作系统调度程序。无论你做什么 - 处理时间表,优先事项或你转过的任何旋钮 - 你都无法可靠地完成它。
您已经支持发现同步机制的需求 - 互斥体,信号量,条件变量,线程障碍等。您想要做的就是它们存在的原因以及您应该使用什么来实现目标。
关于你的上一个问题,pthread_join
从死的,可连接的(即未分离的)线程中回收一些资源,并允许你检查过期线程中的任何返回变量。在你的程序中,它们主要用作阻塞机制。也就是说,main
将阻止这些调用,直到线程到期为止。如果没有pthread_joins
,您的main
将会结束并且流程将会死亡,包括您创建的主题。如果您不想加入线程并且在main
中没有做任何有用的事情,那么在pthread_exit
中使用main
,因为这将允许main退出但线程继续处理。
答案 1 :(得分:0)
首先,fork
创建第二个进程,而创建一个线程会在同一个进程中创建一个“可调度的工作单元”。
让两个不同的进程交错通常是让操作系统运行的简单问题。但是,在一个过程中,您需要更多地了解操作系统如何选择运行多个线程中的哪一个。
你可以人为地通过从每个线程调用sleep来进行不同时间的交互来获取线程的输出。也就是说,创建线程A(将其编码为输出一行,然后睡眠为100)然后创建线程B(将其编码为输出一行然后再睡50,等等)
我理解想要了解线程如何并行运行,类似于进程。但是,这是一个真正的要求还是只是一个“动物园”请求?