信号量Semaphore的基本使用


        Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个。一般的用法是用于串行化对critical section代码的访问,保证这段代码不会被并行的运行。   


        Semaphore是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为binary semaphore。一般的用法是,用于限制对于某一资源的同时访问。


#include "stdafx.h"
#include <conio.h>
#include <Windows.h>

// 临界资源
int g_sum = 0;

// 1、声明信号量对象句柄
HANDLE g_hSemaphore;

DWORD WINAPI ThreadFunc1(LPVOID lpParam);
DWORD WINAPI ThreadFunc2(LPVOID lpParam);


int _tmain(int argc, _TCHAR* argv[])
{
	// 为了演示方便,输入s开始
	printf("请输入“s”开始创建线程:");
	while (getchar() != 's')
	{
		::Sleep(200);
	}
	printf("\n");

	// 2、创建信号量对象   分别用下面三行代码试试
	//g_hSemaphore = ::CreateSemaphore(NULL, 0, 2, NULL);
	//g_hSemaphore = ::CreateSemaphore(NULL, 1, 2, NULL);
	g_hSemaphore = ::CreateSemaphore(NULL, 2, 2, NULL);
	// 创建线程1
	HANDLE h1 = ::CreateThread(NULL, 0, ThreadFunc1, NULL, 0, NULL);
	if (h1 != NULL)
	{
		printf("主线程:线程1创建成功!\n");
	}
	else
	{
		printf("主线程:线程1创建失败!\n");
	}

	// 创建线程2
	HANDLE h2 = ::CreateThread(NULL, 0, ThreadFunc2, NULL, 0, NULL);
	if (h2 != NULL)
	{
		printf("主线程:线程2创建成功!\n");
	}
	else
	{
		printf("主线程:线程2创建失败!\n");
	}
	// 主线程

	//等待子线程结束
	::WaitForSingleObject(h1, INFINITE);
	::WaitForSingleObject(h2, INFINITE);

	while (1)
	{
		if (_getch() == 'q')
		{
			break;
		}
		::Sleep(100);
	}

	::CloseHandle(h1);
	::CloseHandle(h2);
	::CloseHandle(g_hSemaphore);

	return 0;
}

DWORD WINAPI ThreadFunc1(LPVOID lpParam)
{
	// 3、请求信号量对象
	::WaitForSingleObject(g_hSemaphore, INFINITE);

	int n = 5;
	while (n-- > 0)
	{
		g_sum += 1;

		printf("线程1:g_sum 1111= %d\n", g_sum);
		::Sleep(1000);
	}

	// 4、释放
	::ReleaseSemaphore(g_hSemaphore, 1, NULL);

	printf("线程1:执行完毕!\n");
	return 0;
}

DWORD WINAPI ThreadFunc2(LPVOID lpParam)
{
	// 3、请求信号量对象
	::WaitForSingleObject(g_hSemaphore, INFINITE);

	int n = 5;
	while (n-- > 0)
	{
		g_sum += 10;

		printf("线程2:g_sum 2222= %d\n", g_sum);
		::Sleep(2000);
	}

	// 4、释放
	::ReleaseSemaphore(g_hSemaphore, 1, NULL);

	printf("线程2:执行完毕!\n");
	return 0;
}


猜你喜欢

转载自blog.csdn.net/sichuanpb/article/details/77095905