创建线程的API函数
HANDLE CreateThread(
__in SEC_ATTRS SecurityAttributes,
__in ULONG StackSize, // initial stack size
__in SEC_THREAD_START StartFunction, // thread function
__in PVOID ThreadParameter, // thread argument
__in ULONG CreationFlags, // creation option
__out PULONG ThreadId // thread identifier
);
在这里我们只用到了第三个和第四个参数,第三个参数传递了一个函数的地址,也是我们要指定的新的线程,第四个参数是传给新线程的参数指针。
多线程编程示例1:
#include "stdafx.h"
#include "iostream"
#include <Windows.h>
using namespace std;
DWORD WINAPI Func(LPVOID lpParameter)
{
while (1)
{
cout << "Func Display!" << endl;
Sleep(500);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread = CreateThread(NULL,0,Func,NULL,0,NULL);
CloseHandle(hThread);
while (1)
{
cout << "Main Display!" <<endl;
Sleep(1000);
}
return 0;
}
编译运行发现主线程(_tmain函数)和自定义进程(Func函数)是随机交替进行的;
其中Sleep()函数是用来暂停线程的执行的,原型如下:
VOID WINAPI Sleep(
__in DWORD dwMilliseconds
);
参数dwMilliseconds单位是毫秒,比如Sleep(1000)表示暂停1秒;
共享资源独占
根据上述程序代码我们知道每当Fun函数和main函数输出内容后就会输出换行,但是根据运行结果我们看到的确是有的时候程序输出换行了,有的时候确没有输出换行,甚至有的时候是输出两个换行。这是什么原因呢?
将要输出endl(也就是清空缓冲区并换行,在这里我们可以不用理解什么事缓冲区),但此时main函数确得到了运行的机会,此时Fun函数还没有来得及输出换行就把CPU让给了main函数,而这时main函数就直接在Fun display!后输出main display!,至于为什么有的时候程序会连续输出两个换行,读者可以采用同样的分析方法来分析,在这里我就不多讲了,留给读者自己思考了。
这涉及到多线程的同步问题。对于一个资源被多个线程共用会导致程序的混乱,我们的解决方法是只允许一个线程
拥有对共享资源的独占,这样就能够解决上面的问题了。
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner, // initial owner
LPCTSTR lpName // object name
);
该函数用于创造一个独占资源,第一个参数我们没有使用,可以设为NULL,第二个参数指定该资源初始是否归属
创建它的进程,第三个参数指定资源的名称。
调用代码示例如下:
HANDLE hMutex = CreateMutex(NULL,TRUE,"screen");
这条语句创造了一个名为screen并且归属于创建它的进程的资源。
BOOL ReleaseMutex(HANDLE hMutex // handle to mutex);
该函数用于释放一个独占资源,进程一旦释放该资源,该资源就不再属于它了,如果还要用到,需要重新申请得到该资源。申请资源的函数如下:
DWORD WaitForSingleObject(
HANDLE hHandle, // handle to object
DWORD dwMilliseconds // time-out interval
);
第一个参数指定所申请的资源的句柄,第二个参数一般指定为INFINITE,表示如果没有申请到资源就一直等待该资源,如果指定为0,表示一旦得不到资源就返回,也可以具体地指定等待多久才返回,单位是毫秒。
多线程编程示例2:
#include "stdafx.h"
#include "iostream"
#include <Windows.h>
using namespace std;
HANDLE hMutex;
DWORD WINAPI Func(LPVOID lpParameter)
{
while (1)
{
WaitForSingleObject(hMutex,INFINITE);
cout << "Func Display!" << endl;
Sleep(500);
ReleaseMutex(hMutex);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread = CreateThread(NULL,0,Func,NULL,0,NULL);
CloseHandle(hThread);
hMutex = CreateMutex(NULL,FALSE,_T("screen"));
while (1)
{
WaitForSingleObject(hMutex,INFINITE);
cout << "Main Display!" <<endl;
Sleep(1000);
ReleaseMutex(hMutex);
}
return 0;
}