在看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了一遍。