执行线程 - 输出原因
我试图运行下面的代码。在这个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
Value参数= 0
Value参数= 0
我的线程id是139919964464896
参数值= 0
Value参数= 0
这里,我无法弄清楚:
- 为什么行我的线程ID为139919964464896得到,而线值参数= 0获取打印打印两次四次。
- 为什么当传递的参数初始化为5并增加到6时,该值会打印为0?
请问,有人可以帮助我吗?提前致谢!
为什么行我的线程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
或调用fork()
第二次之前调用fflush(stdout);
。
很明显,在第一个fork之后,你有两个进程,它们都会创建一个线程。所以你会看到两个线程的输出。
你的错误是你怎么会在这里解释线程参数:
int i = atoi(param);
特性参数的值是“&我”,从“主()”函数,所以参数是一个真正的int*
对象已被转换为void*
指针。然而,用“atoi”,你把它当作一个字符串来对待。
替换符合:
int* typed_param = (int*) param;
int i = *typed_param;
然后事情应该是有意义的。
感谢您的纠正。请你也可以帮助我的第一点,为什么id的线程打印两次和参数值4次? – Neha
我刚开始阅读操作系统,这是很多有用的信息。非常感谢解释! :) – Neha
不客气! –