之所以要学习一下多线程,最主要的目的是要学习多线程间的同步互斥等控制,而不是学习多线程本身,或者怎么用程序编写多线程。最重要的是利用程序控制多线程,防止在多线程环境中发生死锁的现象发生,这才是这个系列的笔记的中心,其它的都是了解的东西。人的精力和时间真的是有限的,至少我是这样的。所以抓住主线的东西,那些细枝末节在用到的时候,看一下就可以了,根本不用记住,了解它,知道他是怎么回事,是个什么东西就好了。在开始学习多线程之前,先了解一下他的一些语言的工具,然后在利用多线程学习线程之间的同步和互斥关系。
首先用C\C++语言对多线程做一个入门的了解,深入的分析CreateThread与_beginthreadx的本质区别。
首先看下面的代码,先写出来一个多线程的程序来:
#include <stdio.h> #include <windows.h> //子线程的函数 //DWORD是unsigned long //WINAPI是_stdcall表明函数参数的入栈的顺序:表明是函数参数列表的入栈顺序是从左向右还是从右向左 //LPVOID是void* DWORD WINAPI ThreadFun(LPVOID PM) { printf("子线程的ID号为:%d\n", GetCurrentThreadId()); printf("子线程输出Hello World!\n"); return 0; } int main() { //HANDLE是void*,void*可以接受任何指针类型的数值对它进行赋值行为 HANDLE handle = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL); WaitForSingleObject(handle, INFINITE); return 0; }
运行的结果:
下面说一下用到的两个函数:
(1)CreateThread函数
HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); //函数说明:创建一个新的线程 //第一个参数表示线程内核对象的安全属性,一般传入NULL表示使用默认。它是一个指向SECURITY_ATTRIBUTES型态结构的指针。在Windows 98中忽略该参数。在Windows NT中,它被设为NULL //第二个参数表示新线程的初始堆栈大小,默认值为0(1MB)。在任何情况下,Windows根据需要动态延长堆栈的大小 //第三个参数表示新线程所执行的线程函数的地址,多个线程可以使用同一个函数地址,函数名称没有限制,但是必须以下列形式声明:DWORD WINAPI ThreadProc (PVOID pParam); //第四个参数表示传递给线程函数ThreadProc的参数。这样主线程和从属线程就可以共享数据。 //第五个参数指定额外的标志来控制线程的创建,为0表示创建线程之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样就无法调度,直到调用ResumeThread() //第六个参数是指向DWORD的一个指针,将获得线程的ID号,传入NULL表示不需要返回线程ID号。 //函数返回值:创建成功返回线程的句柄,失败返回NULL
注意:线程互斥的提前说明,临界区要在线程执行前初始化,因为线程一但被建立即开始运行(除非手工挂起),在线程建立后在初始化临界区可能出现问题
如:孙鑫MFC中的现象
(2)WaitForSingleObject
DWORD WINAPI WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ); //函数说明: //第一个参数为要等待的内核对象 //第二个参数为最长等待时间,以毫秒为单位,如传入5000就是等待5秒还没发生事件就不等了,传入0就立即返回,传入INFINITE表示无限等待 //上面的代码表示:线程的句柄在线程运行的时候是未触发的,线程运行结束,句柄变处于触发状态。所以可以用WaitForSingleObject()来等待一个线程结束运行 //函数返回值:在指定的时间内对象被触发返回
参考文章:
http://www.cnblogs.com/BeyondTechnology/archive/2010/08/30/1813086.html
http://blog.csdn.net/morewindows/article/details/7421759
原文:http://www.cnblogs.com/stemon/p/4370069.html