Windows下的四种线程同步方法

一、Critical Section

Critical section(临界区)用来实现“排他性占有”。适用范围是单一进程 的各线程之间。它是:

  1. 一个局部性对象,不是一个核心对象。
  2. 快速而有效率。
  3. 不能够同时有一个以上的 critical section 被等待。
  4. 无法侦测是否已被某个线程放弃。

例子

#include <iostream>
#include <process.h>
#include <afxmt.h>
using namespace std;


CRITICAL_SECTION cs;//定义临界区对象

int g_count = 30;

DWORD  _stdcall  proc1(LPVOID param)
{
	while (g_count > 0)
	{
		EnterCriticalSection(&cs);//进入临界区
		cout << "窗口1卖-->" << g_count-- << endl;
		LeaveCriticalSection(&cs);//离开临界区
		Sleep(100);
	}
	
	
	return 0;
}

DWORD  _stdcall  proc2(LPVOID param)
{

	while (g_count > 0)
	{
		EnterCriticalSection(&cs);//进入临界区
		cout << "窗口2卖-->" << g_count-- << endl;
		LeaveCriticalSection(&cs);//离开临界区
		Sleep(100);
	}
	
	return 0;
}


int main()
{
	HANDLE handle_array[2];

	InitializeCriticalSection(&cs);//初始化临界区
	handle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL);
	handle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL);

	WaitForMultipleObjects(2, handle_array, true, INFINITE);
	DeleteCriticalSection(&cs);//删除临界区
	system("pause");

	return 0;
}

二、Mutex

Mutex 是一个核心对象,可以在不同的线程之间实现“排他性占有”,甚 至即使那些线程分属不同进程。它是:

  1. 一个核心对象。
  2. 如果拥有 mu tex 的那个线程结束,则会产生一个 “abandoned” 错 误信息。
  3. 可以使用 Wait...() 等待一个 mu tex。
  4. 可以具名,因此可以被其他进程开启。
  5. 只能被拥有它的那个线程释放(released)。

例子

#include <iostream>
#include <process.h>
#include <afxmt.h>
using namespace std;


HANDLE g_mutex;//定义锁对象

int g_count = 30;

DWORD  _stdcall  proc1(LPVOID param)
{
	while (g_count > 0)
	{
		WaitForSingleObject(g_mutex, INFINITE);//等待锁
		cout << "窗口1卖-->" << g_count-- << endl;
		ReleaseMutex(g_mutex);//释放锁
		Sleep(100);
	}


	return 0;
}

DWORD  _stdcall  proc2(LPVOID param)
{

	while (g_count > 0)
	{
		WaitForSingleObject(g_mutex, INFINITE);//等待锁
		cout << "窗口2卖-->" << g_count-- << endl;
		ReleaseMutex(g_mutex);//释放锁
		Sleep(100);
	}

	return 0;
}


int main()
{
	HANDLE handle_array[2];

	g_mutex = CreateMutex(NULL, false, NULL);//创建锁
	handle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL);
	handle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL);

	WaitForMultipleObjects(2, handle_array, true, INFINITE);
	CloseHandle(g_mutex);//关闭锁
	system("pause");

	return 0;
}

三、Semaphore

Semaphore 被用来追踪有限的资源。它是:

  1. 一个核心对象。
  2. 没有拥有者。
  3. 可以具名,因此可以被其他进程开启。
  4. 可以被任何一个线程释放(released)。

例子

#include <iostream>
#include <process.h>
#include <afxmt.h>
using namespace std;


HANDLE g_semaphore;//信号量

int g_count = 30;

DWORD  _stdcall  proc1(LPVOID param)
{
	while (g_count > 0)
	{
		WaitForSingleObject(g_semaphore, INFINITE);//进入临界区
		cout << "窗口1卖-->" << g_count-- << endl;
		ReleaseSemaphore(g_semaphore, 1, NULL);//离开临界区
		Sleep(100);
	}


	return 0;
}

DWORD  _stdcall  proc2(LPVOID param)
{

	while (g_count > 0)
	{
		WaitForSingleObject(g_semaphore, INFINITE);//进入临界区
		cout << "窗口2卖-->" << g_count-- << endl;
		ReleaseSemaphore(g_semaphore, 1, NULL);//离开临界区
		Sleep(100);
	}

	return 0;
}


int main()
{
	HANDLE handle_array[2];


	g_semaphore = CreateSemaphore(NULL, 1, 1, NULL);//创建信号量总数为1,并且设置为signaled状态

	handle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL);
	handle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL);

	WaitForMultipleObjects(2, handle_array, true, INFINITE);
	CloseHandle(g_semaphore);
	system("pause");

	return 0;
}

 

四、Event Object

Event object 通常使用于 overlapped I/O(第6章),或用来设计某些自定 义的同步对象。它是:

  1. 一个核心对象。
  2. 完全在程序掌控之下。
  3. 适用于设计新的同步对象。
  4. “要求苏醒”的请求并不会被储存起来,可能会遗失掉。
  5. 可以具名,因此可以被其他进程开启。

例子

#include <iostream>
#include <process.h>
#include <afxmt.h>
using namespace std;


HANDLE g_event;//事件

int g_count = 30;

DWORD  _stdcall  proc1(LPVOID param)
{
	while (g_count > 0)
	{
		WaitForSingleObject(g_event, INFINITE);//进入临界区
		cout << "窗口1卖-->" << g_count-- << endl;
		SetEvent(g_event);//离开临界区
		Sleep(100);
	}


	return 0;
}

DWORD  _stdcall  proc2(LPVOID param)
{

	while (g_count > 0)
	{
		WaitForSingleObject(g_event, INFINITE);//进入临界区
		cout << "窗口2卖-->" << g_count-- << endl;
		SetEvent(g_event);//离开临界区
		Sleep(100);
	}

	return 0;
}


int main()
{
	HANDLE handle_array[2];


	g_event = CreateEvent(NULL, false, false, NULL);
	SetEvent(g_event);


	handle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL);
	handle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL);

	WaitForMultipleObjects(2, handle_array, true, INFINITE);
	CloseHandle(g_event);
	system("pause");

	return 0;
}

 

 

注意:关于几个函数如何使用以及每个参数什么意思,请自行百度或者查阅相关资料。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值