我正在尝试运行以下代码。在question的帮助下,我能够理解应该创建多少进程和线程,但是更进一步,我尝试让线程执行一个函数。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *runner(void *param) {
int i = atoi(param);
printf("My thread id is %ld\n",pthread_self());
printf("\nValue of parameter = %d", i);
pthread_exit(0);
}
int main()
{
int i = 5;
pid_t pid;
pthread_t tid;
pthread_attr_t attr;
pid = fork(); wait(NULL);
if (pid == 0) { /* Child Process */
fork(); wait(NULL);
pthread_attr_init(&attr);
i++;
pthread_create(&tid, &attr, runner, &i);
pthread_join(tid, NULL);
}
fork(); wait(NULL);
printf("\n\n");
return 0;
}
这个输出是: 我的帖子ID是139919964464896
参数值= 0
参数值= 0
我的帖子ID是139919964464896
参数值= 0
参数值= 0
在这里,我无法弄明白:
拜托,有人可以帮我吗?提前谢谢!
答案 0 :(得分:2)
您的错误在于如何解释线程参数:
int i = atoi(param);
param的值是“main()”函数中的“&amp; i”,因此param实际上是一个已转换为int*
指针的void*
对象。但是,对于“atoi”,您将其视为字符串。
将该行替换为:
int* typed_param = (int*) param;
int i = *typed_param;
然后事情应该有意义。
答案 1 :(得分:2)
为什么我的线程ID为139919964464896的行被打印两次 而参数= 0的行值被打印四次。
当你fork()
时,每个进程也从父进程中获取缓冲区的副本(在所有其他内容中)。通常stdout
(标准输出)是行缓冲的。这意味着当您打印换行符(\n
)或显式刷新缓冲区,即调用fflush(stdout);
时,将刷新缓冲区
当您第一次拨打fork()
时,缓冲区中没有任何内容(即您目前尚未打印任何内容)。所以没有区别。但是当你第二次调用fork()
时,未被刷新的整个缓冲区将被复制到子进程。当它退出的过程时,两个进程都刷新它们的缓冲区。因此Value of parameter = 0
打印两次。
但是行My thread id is ....
没有打印两次,因为\n
强制刷新缓冲区。
所以要么在最后添加换行符:
printf("\nValue of parameter = %d\n", i);
^ forces flushing the output buffer
或者在第二次致电fflush(stdout);
之前致电fork()
。
显然在第一个fork之后,你有两个进程,它们都将创建一个线程。所以你会看到两个线程的输出。