首页 > pthread_create新建线程,为什么新线程执行的函数有时候会被调用两次?

pthread_create新建线程,为什么新线程执行的函数有时候会被调用两次?

在看apue的第11章,按照书上的代码打了如下:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

pthread_t ntid;


void printids(const char *s){
    pid_t pid;
    pthread_t tid;
    
    pid = getpid();
    tid = pthread_self();

    printf("%s:pid %lu tid %lu (0x%lx)\n", s, (unsigned long) pid, (unsigned long) tid, (unsigned long)tid);
}

void *thr_fn(void *arg){
    printids("new thread:");
    return ((void *)0);
}

int main(){
    int err;
    err = pthread_create(&ntid, NULL, thr_fn, NULL);
    printids("main thread:");
    exit(0);
}

有时候只输出

main thread::pid 22506 tid 139699542841088 (0x7f0e55a05700)

这个我能理解,在主线程结束的时候,新线程还没来的及执行,就终止了。

多数情况是这样的

new thread::pid 22680 tid 140091717809920 (0x7f69a5137700)
main thread::pid 22680 tid 140091726059264 (0x7f69a5915700)

这个也是正常,但是有时候会出现

main thread::pid 22698 tid 140224862336768 (0x7f88a51bb700)
new thread::pid 22698 tid 140224854087424 (0x7f88a49dd700)
new thread::pid 22698 tid 140224854087424 (0x7f88a49dd700)

这是为什么?是什么导致新线程调了printids两次?


首先,这个程序是错误的,在exit()的时候会在stdout上发生竞争。
你要明白,发生竞争之后出现什么情况都不稀奇,所以不要深究这个原因了,没有意义,这跟stdio的实现相关。

举个可能的场景满足你的好奇心,比如:
新线程的printf在写完缓冲区之后执行flush——调用write,再要把已经write过的数据从缓冲区中删掉,但是在删除之前,main线程的exit也要flush stdout,就可能把已经flush过的数据又flush了一遍。


主线程退出之前等一下子线程

【热门文章】
【热门文章】