多线程出现了一些不解!!!求解!!
程序如下,好简单:
#include<stdio.h>
#include <windows.h>
DWORD WINAPI ThreadProc(LPVOID lpParameter){
printf("child!\n");
Sleep(1000);
return 0;
}
void main(){
CreateThread(NULL,2,ThreadProc,NULL,0,NULL);
printf("main\n");
return ;
}
主线程创建一个子线程,但是运行结果好奇怪,
有时输出:
main
但有时输出:
main
child
main
总之有时会输出两个main!!! 为什么会这样??会什么会有两个main打印出来?
但是当子线程的Sleep(1000)放在第一句就只会输出main.
我觉得是我对多线程的理解不够深入吧,我怎么也不能理解怎么会出现两个 main?
请大牛们帮帮!!!
[解决办法]
printf是有缓冲区的,所以不是线程安全的,C库在编译时可以加选项在其内部封上一层锁,但是我们并不知道编译时候是什么样的,所以必须认为它是非线程安全的。
1,main : printf main,将4字节加入缓冲,发现\n决定刷新缓冲区,但是此刻发生线程切换, 此时main:printf的写指针指向5字节位置没有归位,而局部读指针已经准备好了指向缓冲区头部。
2,子线程操作printf,因为写指针仍然在5字节位置,所以继续向后追加child到缓冲区,遇见\n决定刷新缓冲区,于是再次write出“main/nchild\n”,写指针和读指针都归位。
3,main线程的从局部读指针写出直到5字节位置。
于是发生了main\nchild\nmain\n。
其实单纯的printf操作FILE变量的话想出现这种不一致现象还比较难,正是因为printf的实现喜欢把一些FILE里的参数局部化存储,于是就造成了很明显的很容易重现的不一致。