执行线程 - 输出原因

时间:2015-07-11 23:48:15

标签: c multithreading pthreads

我正在尝试运行以下代码。在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

在这里,我无法弄明白:

  1. 为什么行我的主题ID为139919964464896 会被打印两次,而参数值= 0 会被打印四次。
  2. 当传递的参数初始化为5并增加到6时,为什么值打印为0?
  3. 拜托,有人可以帮我吗?提前谢谢!

2 个答案:

答案 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之后,你有两个进程,它们都将创建一个线程。所以你会看到两个线程的输出。