前期知识准备
CreateThread():
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //
DWORD dwStackSize, //
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadID
);
参数含义:
lpThreadAttrivutes:指向SECURITY_ATTRIBUTES的指针,用于定义新线程的安全属性,一般设置成NULL;
dwStackSize:分配以字节数表示的线程堆栈的大小,默认值是0;
lpStartAddress:指向一个线程函数地址。每个线程都有自己的线程函数,线程函数是线程具体的执行代码;
lpParameter:传递给线程函数的参数;
dwCreationFlags:表示创建线程的运行状态,其中CREATE_SUSPEND表示挂起当前创建的线程,而0表示立即执行当前创建的进程;
lpThreadID:返回新创建的线程的ID编号;
如果函数调用成功,则返回新线程的句柄,调用WaitForSingleObject函数等待所创建线程的运行结束。函数的格式如下:
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMillis,
);
参数的含义如下:
hHandle:指定对象或时间的句柄;
dwMilliseconds:等待时间,以毫秒为单位,当超过等待时间时,此函数返回。如果参数设置为0,则该函数立即返回;如果设置成INFINITE,则该函数直到有信号才返回。
实例一:
Windows下,利用高级编程语言(例如:VS)调用CreateThread()创建两个线程:A:顺序递增输出1-1000的自然数,B:逆序递减输出1000-1的自然数;
#include<Windows.h>
#include<stdio.h>
DWORD WINAPI cthread1(LPVOID pm) {
//LPVOID 是没有类型的指针
int i=1000;
while (i >=0) {
printf("thread 1: %d\n", i);
Sleep(0.5);
i--;
}
//int *x = (int *)pm;
//printf("%d\n", *x);打印x;
return 0;
}
DWORD WINAPI cthread2(LPVOID pm) {
//LPVOID 是没有类型的指针
int i=1;
while (i <= 1000) {
printf("thread 2: %d\n",i);
Sleep(0.5);
i++;
}
return 0;
}
int main() {
HANDLE handle1 = CreateThread(NULL, 0, cthread1, NULL, 0,NULL);
//HANDLE handle1 = CreateThread(NULL, 0, cthread1, &x, 0,NULL);传递参数 x;
HANDLE handle2 = CreateThread(NULL, 0, cthread2, NULL, 0,NULL);
WaitForSingleObject(handle1, INFINITE);
WaitForSingleObject(handle1, INFINITE);
system("pause");
return 0;
}
互斥器(Mutex):
使用方法:
1、创建一个互斥器:CreateMutex;
2、打开一个已经存在的互斥器:OpenMutex;
3、获得互斥器的拥有权:WaitForSingleObject、WaitForMultipleObjects 等一类等待的函数……(可能造成阻塞);
4、释放互斥器的拥有权:ReleaseMutex;
5、关闭互斥器:CloseHandle;
HANDLE WINAPI CreateMutex(
__in_opt LPSECURITY_ATTRIBUTES lpMutexAttributes,
__in BOOL bInitialOwner,
__in_opt LPCTSTR lpName
);
lpMutexAttributes : 第一个参数表示安全控制,一般直接传入NULL。
bInitialOwner第二个参数用来确定互斥量的初始拥有者。
如果传入TRUE表示互斥量对象内部会记录创建它的线程的线程ID号并将递归计数设置为1,由于该线程ID非零,所以互斥量处于未触发状态,表示互斥量为创建线程拥有。
如果传入FALSE,那么互