笔记:windows环境下线程编程(C++实现同步与互斥)

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;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中杯可乐多加冰

请我喝杯可乐吧,我会多加冰!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值