Windows系统为我们提供了相关API,我们可以使用他们来进行多线程编程。
1.创建一个线程,参数解释如下:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD:线程安全相关的属性,常置为NULL
SIZE_T dwStackSize,//initialstacksize:新线程的初始化栈的大小,可设置为0
LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction:被线程执行的回调函数,也称为线程函数
LPVOID lpParameter,//threadargument:传入线程函数的参数,不需传递参数时为NULL
DWORD dwCreationFlags,//creationoption:控制线程创建的标志
LPDWORD lpThreadId//threadidentifier:传出参数,用于获得线程ID,如果为NULL则不返回线程ID
)
2.创建一个信号量,参数解释如下:
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // 安全属性指针
LONG lInitialCount, // 初始计数
LONG lMaximumCount, // 最大计数
LPCTSTR lpName // 对象名指针
);
3.P操作,参数解释如下:
DWORD WaitForSingleObject(
HANDLE hObject, //指明一个内核对象的句柄
DWORD dwMilliseconds); //等待时间
4.V操作,参数解释如下:
ReleaseSemaphore(
HANDLE hSemaphore,
LONG lReleaseCount,
LPLONG lpPreviousCount
);
hSemaphore 是要增加的信号量句柄。
lReleaseCount 是增加的计数。
lpPreviousCount 是增加前的数值返回。
5:基础示例:
#include <iostream>
#include <windows.h>
using namespace std;
DWORD WINAPI Fun(LPVOID lpParamter)//子线程
{
for (int i = 0; i < 10; i++)
{
cout << "A Thread Fun Display!" << endl;
Sleep(200);//每次休眠200ms
}
return 0;
}
int main()
{
HANDLE hThread = CreateThread(NULL, 0, Fun, NULL, 0, NULL);//创建一个最简单的子线程
CloseHandle(hThread);//关闭句柄
for (int i = 0; i < 10; i++)
{
cout << "Main Thread Display!" << endl;
Sleep(500);//每次休眠500ms
}
system("pause");
return 0;
}
6:进阶示例:
问题描述:桌上有一空盘,最多允许存放一个水果。爸爸可向盘中放一个苹果或放一个桔子,儿子专等吃盘中的桔子,女儿专等吃苹果。 编写Windows下父亲儿子女儿放取水果进程同步的演示程序。
#include<iostream>
#include <stdio.h>
#include<string.h>
#include<windows.h>
using namespace std;
HANDLE g_apple = 0;//女儿线程互斥:表示可否取苹果
HANDLE g_orange = 0;//儿子线程互斥:表示可否取桔子
HANDLE g_hMutex = 0; //父亲线程互斥:表示可否向盘中放水果
bool g_continue = true; //控制程序运行和结束
DWORD WINAPI Father(LPVOID); //父亲线程
DWORD WINAPI Son(LPVOID);//儿子线程
DWORD WINAPI Daughter(LPVOID);//女儿线程
int main()
{
//创建各个信号量
g_orange = CreateSemaphore(NULL, 0, 1, NULL);
g_apple = CreateSemaphore(NULL, 0, 1, NULL);
g_hMutex = CreateSemaphore(NULL, 1, 1, NULL);
DWORD threadID[3];
HANDLE hThreads[3];
//创建父亲线程
hThreads[0] = CreateThread(NULL, 0, Father, NULL, 0, &threadID[0]);
if (hThreads == NULL) return -1;
//创建儿子线程
hThreads[1] = CreateThread(NULL, 0, Son, NULL, 0, &threadID[1]);
if (hThreads == NULL) return -1;
//创建女儿线程
hThreads[2] = CreateThread(NULL, 0, Daughter, NULL, 0, &threadID[2]);
if (hThreads == NULL) return -1;
while (g_continue){
if (getchar()){ //按回车后终止程序运行
g_continue = false;
}
}
return 0;
}
//父亲线程
DWORD WINAPI Father(LPVOID lpPara)
{
while (g_continue){
WaitForSingleObject(g_hMutex, INFINITE);//INFINITE表示无限等待,一直等到当g_hMutex为1时才进行下面操作
int m = rand() % 2;//rand取随机数,随机放苹果或者桔子
if (m == 1) {
cout<< "父亲放入一个苹果!" <<endl;
Sleep(1500);
ReleaseSemaphore(g_apple, 1, NULL);
}
else{
cout<< "父亲放入一个桔子!" <<endl;
Sleep(1500);
ReleaseSemaphore(g_orange, 1, NULL);
}
}
return 0;
}
//女儿线程
DWORD WINAPI Daughter(LPVOID lpPara)
{
while (g_continue){
WaitForSingleObject(g_apple, INFINITE);
cout<< "女儿吃到一个苹果!" <<endl;
Sleep(1500);
ReleaseSemaphore(g_hMutex, 1, NULL);
}
return 0;
}
//儿子线程
DWORD WINAPI Son(LPVOID lpPara)
{
while (g_continue){
WaitForSingleObject(g_orange, INFINITE);
cout<< "儿子吃到一个桔子!" <<endl;
Sleep(1500);
ReleaseSemaphore(g_hMutex, 1, NULL);
}
return 0;
}