C 执行线程-输出原因

C 执行线程-输出原因,c,multithreading,pthreads,C,Multithreading,Pthreads,我正在尝试运行以下代码。有了它的帮助,我能够理解应该创建多少进程和线程,但更进一步,我尝试让线程执行一个函数 #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()); pri

我正在尝试运行以下代码。有了它的帮助,我能够理解应该创建多少进程和线程,但更进一步,我尝试让线程执行一个函数

#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;
}
#包括
#包括
#包括
无效*流道(无效*参数){
int i=atoi(参数);
printf(“我的线程id是%ld\n”,pthread_self());
printf(“\n参数值=%d”,i);
pthread_退出(0);
}
int main()
{
int i=5;
pid_t pid;
pthread_t tid;
pthread_attr_t attr;
pid=fork();等待(NULL);
如果(pid==0){/*子进程*/
fork();等待(NULL);
pthread_attr_init(&attr);
i++;
pthread_创建(&tid,&attr,runner,&i);
pthread_join(tid,NULL);
} 
fork();等待(NULL);
printf(“\n\n”);
返回0;
}
其输出为: 我的线程id是139919964464896

参数值=0

参数值=0

我的线程id是139919964464896

参数值=0

参数值=0

在这里,我无法理解:

  • 为什么线我的线程id是139919964464896会打印两次,而参数=0的线值会打印四次
  • 当传递的参数已初始化为5并递增为6时,为什么值打印为0

  • 拜托,有人能帮我吗?提前谢谢

    您的错误在于如何在此处解释线程参数:

    int i = atoi(param); 
    
    param的值是“main()”函数中的“&i”,因此param实际上是一个
    int*
    对象,已转换为
    void*
    指针。然而,对于“atoi”,您将其视为字符串

    将该行替换为:

    int* typed_param = (int*) param;
    int i = *typed_param;
    

    然后事情就有了意义。

    您的错误在于如何解释此处的线程参数:

    int i = atoi(param); 
    
    param的值是“main()”函数中的“&i”,因此param实际上是一个
    int*
    对象,已转换为
    void*
    指针。然而,对于“atoi”,您将其视为字符串

    将该行替换为:

    int* typed_param = (int*) param;
    int i = *typed_param;
    
    然后事情就应该有意义了

    为什么我的线程id为139919964464896的行会打印两次 而参数=0的行值会打印四次

    当您
    fork()
    时,每个进程也会从父进程获取缓冲区的副本(以及所有其他内容)。通常,
    stdout
    (标准输出)是行缓冲的。这意味着在打印换行符(
    \n
    )或显式刷新缓冲区(即调用
    fflush(stdout))时,缓冲区将被刷新
    当您第一次调用
    fork()
    时,缓冲区中没有任何内容(即,到目前为止您还没有打印任何内容)。所以这没什么区别。但当您第二次调用
    fork()
    时,未刷新的整个缓冲区将被复制到子进程。当进程退出时,两个进程都会刷新其缓冲区。因此,参数=0的
    值被打印两次

    但是行
    我的线程id是….
    没有打印两次,因为
    \n
    强制刷新缓冲区

    因此,在末尾添加一个换行符:

    printf("\nValue of parameter = %d\n", i);
                                     ^ forces flushing the output buffer
    
    或者调用
    fflush(stdout)fork()
    之前执行code>

    显然,在第一个fork之后,您有两个进程,它们都将分别创建一个线程。您将看到两个线程的输出

    为什么我的线程id为139919964464896的行会打印两次 而参数=0的行值会打印四次

    当您
    fork()
    时,每个进程也会从父进程获取缓冲区的副本(以及所有其他内容)。通常,
    stdout
    (标准输出)是行缓冲的。这意味着在打印换行符(
    \n
    )或显式刷新缓冲区(即调用
    fflush(stdout))时,缓冲区将被刷新
    当您第一次调用
    fork()
    时,缓冲区中没有任何内容(即,到目前为止您还没有打印任何内容)。所以这没什么区别。但当您第二次调用
    fork()
    时,未刷新的整个缓冲区将被复制到子进程。当进程退出时,两个进程都会刷新其缓冲区。因此,参数=0的
    值被打印两次

    但是行
    我的线程id是….
    没有打印两次,因为
    \n
    强制刷新缓冲区

    因此,在末尾添加一个换行符:

    printf("\nValue of parameter = %d\n", i);
                                     ^ forces flushing the output buffer
    
    或者调用
    fflush(stdout)fork()
    之前执行code>


    显然,在第一个fork之后,您有两个进程,它们都将分别创建一个线程。您将看到两个线程的输出。

    谢谢您的更正。请你也帮我回答第一点,为什么线的id打印两次,参数的值打印4次?谢谢你的更正。请你也帮我回答第一点,为什么线程的id打印两次,参数的值打印4次?我刚开始阅读操作系统,这是很多有用的信息。谢谢你的解释!:)我刚开始阅读操作系统,这是很多有用的信息。谢谢你的解释!:)