Basic use of semaphore Semaphore


        A Mutex is a key that a person can take to enter a room, and hand the key to the first person in the queue when they come out. Common usage is to serialize access to critical section code, ensuring that this code will not be run in parallel.   


        Semaphore is a room that can accommodate N people. If people are not satisfied, they can go in. If they are full, they have to wait for someone to come out. For the case of N=1, it is called binary semaphore. The general usage is to limit simultaneous access to a resource.


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

// critical resource
int g_sum = 0;

// 1. Declare the semaphore object handle
HANDLE g_hSemaphore;

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


int _tmain(int argc, _TCHAR* argv[])
{
	// For the convenience of demonstration, enter s to start
	printf("Please enter "s" to create a thread: ");
	while (getchar() != 's')
	{
		::Sleep(200);
	}
	printf("\n");

	// 2. Create a semaphore object and try the following three lines of code respectively
	//g_hSemaphore = ::CreateSemaphore(NULL, 0, 2, NULL);
	//g_hSemaphore = ::CreateSemaphore(NULL, 1, 2, NULL);
	g_hSemaphore = ::CreateSemaphore(NULL, 2, 2, NULL);
	// create thread 1
	HANDLE h1 = ::CreateThread(NULL, 0, ThreadFunc1, NULL, 0, NULL);
	if (h1 != NULL)
	{
		printf("Main thread: thread 1 created successfully!\n");
	}
	else
	{
		printf("Main thread: Failed to create thread 1!\n");
	}

	// create thread 2
	HANDLE h2 = ::CreateThread(NULL, 0, ThreadFunc2, NULL, 0, NULL);
	if (h2 != NULL)
	{
		printf("Main thread: Thread 2 created successfully!\n");
	}
	else
	{
		printf("Main thread: failed to create thread 2!\n");
	}
	// main thread

	//Wait for the child thread to finish
	::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. Request semaphore object
	::WaitForSingleObject(g_hSemaphore, INFINITE);

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

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

	// 4, release
	::ReleaseSemaphore(g_hSemaphore, 1, NULL);

	printf("Thread 1: Finished!\n");
	return 0;
}

DWORD WINAPI ThreadFunc2(LPVOID lpParam)
{
	// 3. Request semaphore object
	::WaitForSingleObject(g_hSemaphore, INFINITE);

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

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

	// 4, release
	::ReleaseSemaphore(g_hSemaphore, 1, NULL);

	printf("Thread 2: Finished!\n");
	return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325889133&siteId=291194637