#include <windows.h>
#include <stdio.h>DWORD WINAPI Fun1Proc(LPVOID lpParameter);int main(int argc, char* argv[])
{
HANDLE hThread1;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
printf("main %d thread is runing\n",GetCurrentThreadId());
CloseHandle(hThread1);
return 0;
}DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
printf("thread1 %d is running\n",GetCurrentThreadId());
return 0;
}
为什么会显示的是:
main 4120 thread is running
main 4120 thread is running
thread 2184 is running为什么会有两个main ??
我是个新手~~~
#include <stdio.h>DWORD WINAPI Fun1Proc(LPVOID lpParameter);int main(int argc, char* argv[])
{
HANDLE hThread1;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
printf("main %d thread is runing\n",GetCurrentThreadId());
CloseHandle(hThread1);
return 0;
}DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
printf("thread1 %d is running\n",GetCurrentThreadId());
return 0;
}
为什么会显示的是:
main 4120 thread is running
main 4120 thread is running
thread 2184 is running为什么会有两个main ??
我是个新手~~~
再怎么不同步,也不会有两个main出现把???
以标准C运行库的全局变量errno为例。有的函数会在出错时设置该变量。
假定现在有这样的一个代码段:BOOL fFailure = (system("NOTEPAD.EXE README.TXT") == -1);
if (fFailure) {
switch (errno) {
case E2BIG: // Argument list or environment too big
break;
case ENOENT: // Command interpreter cannot be found
break;
case ENOEXEC: // Command interpreter has bad format
break;
case ENOMEM: // Insufficient memory to run command
break;
}
}假设在调用了system函数之后,并在执行if语句之前,执行上述代码的线程被中断了。另外还假设,这个线程被中断后,同一个进程中的另一个线程开始执行,而且这个新线程将执行另一个C运行库函数,后者设置了全局变量errno。当CPU后来被分配回第一个线程时,对于上述代码中的system函数调用,errno反映的就不再是正确的错误码。为了解决这个问题,每个线程都需要它自己的errno变量。此外,必须有某种机制能够让一个线程引用它自己的errno变量,同时不能让它去碰另一个线程的errno变量。
这仅仅是证明了“标准C/C++运行库最初不是为多线程应用程序而设计”的众多例子中的一个。
在多线程环境中会出问题的C/C++运行库变量和函数有errno,_doserrno,strtok,_wcstok,strerror,_strerror,tmpnam,tmpfile,asctime,_wasctime,gmtime,_ecvt和_fcvt等等。
为了保证C和C++多线程应用程序正常运行,必须创建一个数据结构,并使之与使用了C/C++运行库函数的每个线程关联。然后,在调用C/C++运行库函数时,那些函数必须知道去查找主调线程的数据块,从而避免影响到其他线程。
那么,系统在创建新的线程时,是如何知道要分配这个数据块的呢?答案是它并不知道。系统并不知道应用程序是用C/C++来写的,不知道你调用的函数并非天生就是线程安全的。保证线程安全是程序员的责任。创建新线程时,一定不要调用操作系统的CreateThread函数。相反,必须调用C/C++运行库函数_beginthreadex。
对于_beginthreadex函数,每个线程都有自己的专用_tiddata内存块,它们是从C/C++运行库的堆(heap)上分配的。用_beginthreadex而不要用CreateThread创建线程。而_beginthreadex是用于多线程应用程序的C运行库中函数,要想编译通过,必须在 Project->Setting->c/C++->Code Generation->Use Run Library中选择多线程选项(Multithreaded 或者 Debug Multithreaded)。之后你会发现,使用了多线程运行库之后,即使使用CreateThread函数也不会出错了。
main 4120 thread is running
大概1/10几率会:
main 4120 thread is running
thread 2184 is running没有出现LZ所说的情况
fprintf(stderr,"thread1 %d is running\n",GetCurrentThreadId());好吧,我把代码改这这样,stderr应该不经过缓冲区吧~~~但是结果还是出现了两个main(有时候 出现)...好纠结啊~~~~~~~~~~~~~~
要想真没运行库的缓冲,用这个DWORD WINAPI Fun1Proc(LPVOID lpParameter);
int main(int argc, char* argv[])
{
HANDLE hThread1;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
char ccc[256];DWORD count=
sprintf(ccc,"main %d thread is runing\n",GetCurrentThreadId());
WriteFile(GetStdHandle(-11),ccc,count,&count,0);
CloseHandle(hThread1);
return 0;
}DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
char ccc[256];DWORD count=
sprintf(ccc,"thread1 %d is running\n",GetCurrentThreadId());
WriteFile(GetStdHandle(-11),ccc,count,&count,0);
return 0;
}