线程同步四种方式

四种进程或线程同步互斥的控制方法
      1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 
  2、互斥量:为协调共同对一个共享资源的单独访问而设计的。 
        以上两种只能实现线程互斥,不能实现线程同步,涉及到同步,则需要使用下面两种方法
  3、信号量:为控制一个具有有限数量用户资源而设计。 
  4、事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。 

#include <iostream>
#include <Windows.h>
using namespace std;

//使用互斥对象Mutex来控制线程同步
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int index = 0;
volatile int tickets = 10;
HANDLE hMutex;  //创建的互斥量

void main()
{
	//创建互斥对象,TRUE代表主程序用于互斥对象,线程ID设置为调用线程的ID,
    //递归计数器设置为1,由于ID是非0的,互斥对象开始时不发出通知信号。
	//FALSE互斥对象ID和递归计数器均被设置为0,即互斥对象没有被任何线程所用于,
	//因此它要发出通知信号、
	hMutex = CreateMutex(NULL, TRUE, "tickets");

	if (hMutex)
	{
		if (ERROR_ALREADY_EXISTS == GetLastError())
		{
			cout << "only one instance can run!" << endl;
			return;
		}
	}
	ReleaseMutex(hMutex);

	//创建线程
	HANDLE hThread1;
	HANDLE hThread2;
	
	hThread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
	hThread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);

	CloseHandle(hThread1);
	CloseHandle(hThread2);

	//通过调用一个等待函数,并传递负责保护资源的互斥对象的句柄,
	//线程就能获得共享资源的访问权。
	WaitForSingleObject(hMutex, INFINITE);
	cout << "Main Thread!" << endl;
	ReleaseMutex(hMutex);
	Sleep(4000);

	system("pause");
	
}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
	while (true)
	{
		//请求事件对象
		WaitForSingleObject(hMutex, INFINITE);
		if (tickets > 0)
		{
			Sleep(0);
			cout << "thread1 sell ticket: " << tickets-- << endl;
		}
		else
			break;
		ReleaseMutex(hMutex);
	}
	return 0;
}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
	while (true)
	{
		WaitForSingleObject(hMutex, INFINITE);
		if (tickets > 0)
		{
			Sleep(0);
			cout << "thread2 sell ticket: " << tickets-- << endl;
		}
		else
			break;
		ReleaseMutex(hMutex);
	}
	return 0;
}
//信号量方式

#include <Windows.h>
#include <iostream>
using namespace std;

const int MAX_SEM_COUNT = 10;
const int THREADCOUNT = 12;

HANDLE ghSemaphore; //信号量

DWORD WINAPI ThreadProc(LPVOID);

int main()
{
	HANDLE aThread[THREADCOUNT];
	DWORD ThreadID;
	int i;

	//创建一个信号量,用MAX_SEM_COUNT初始化信号最大数量

	ghSemaphore = CreateSemaphore(
		NULL,   //默认的安全属性
		MAX_SEM_COUNT,  //初始化值
		MAX_SEM_COUNT,  //最多的信号量
		NULL);          //未命名的信号量

	if (ghSemaphore == NULL)
	{
		cout << "CreateSemaphore error: " << GetLastError() << endl;
		return 1;
	}

	//创建工作线程
	for (int i = 0; i < THREADCOUNT; i++)
	{
		aThread[i] = CreateThread(
			NULL,
			0,
			ThreadProc,
			NULL, 0,
			&ThreadID);    //线程ID
		if (aThread[i] == NULL)
		{
			cout << "CreateThread error: " << GetLastError() << endl;
			return 1;
		}
	}

	//等待所有的线程终止
	WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

	//关闭线程和信号量句柄
	Sleep(1000);
	for (int i = 0; i < THREADCOUNT; i++)
		CloseHandle(aThread[i]);
    CloseHandle(ghSemaphore);

	system("pause");
	return 0;
}

DWORD WINAPI ThreadProc(LPVOID)
{
	DWORD dwWaitResult;
	BOOL bContinue = TRUE;

	while (bContinue)
	{
		dwWaitResult = WaitForSingleObject(ghSemaphore, 0);

		switch (dwWaitResult)
		{
		case WAIT_OBJECT_0:
			cout << "Thread " << GetCurrentThreadId() << ": wait succeeded" << endl;
			bContinue = FALSE;

			Sleep(5);
			//释放信号量
			if (! ReleaseSemaphore(ghSemaphore, 1, NULL))
			{
				cout << "ReleaseSemaphore error: " << GetLastError() << endl;
			}
			break;
		case WAIT_TIMEOUT:
			cout << "Thread " << GetCurrentThreadId() << ": wait timed out" << endl;
			break;
		}
	}
	return 1;
}

#include <Windows.h>
#include <iostream>
using namespace std;

//利用事件控制线程同步
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int tickets = 100;
HANDLE g_hEvent;     //用于表示同步事件

void main()
{
	//第一个FALSE:创建一个自动重置事件;如果为TRUE,则是人工重置事件
	//第二个FALSE:用于指明该事件是要初始化为已通知状态(TRUE)还是未通知状态(FALSE)
	//以下为创建一个自动重置事件,且初始状态为未通知事件
	g_hEvent = CreateEvent(NULL, FALSE, FALSE, "tickets");
	if (g_hEvent)
	{
		if (ERROR_ALREADY_EXISTS == GetLastError())
		{
			cout << "only one instance can run! " << endl;
			return ;
		}
	}
	SetEvent(g_hEvent);  //将事件设置为已通知状态

	HANDLE hThread1;
	HANDLE hThread2;

	hThread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
	hThread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);
	CloseHandle(hThread1);
	CloseHandle(hThread2);

	Sleep(4000);
	CloseHandle(g_hEvent);
	system("pause");
}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
	while (true)
	{
		WaitForSingleObject(g_hEvent, INFINITE);
		if (tickets > 0)
		{
			Sleep(1);
			cout << "thread1 sell ticket: " << tickets-- << endl;
			SetEvent(g_hEvent);
		}
		else
		{
			SetEvent(g_hEvent);
			break;
		}
	}
	return 0;
}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
	while (true)
	{
		WaitForSingleObject(g_hEvent, INFINITE);
		if (tickets > 0)
		{
			Sleep(1);
			cout << "thread2 sell ticket: " << tickets-- << endl;
			SetEvent(g_hEvent);
		}
		else
		{
			SetEvent(g_hEvent);
			break;
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值