windows信号量实现读写同步

    windows上的线程同步提供了用户状态下的线程同步和内核状态下的线程同步,内核下的线程同步因为要涉及到内核模式和用户模式的切换,所以消耗是用户模式下的几倍,但是内核下的同步机制不仅适用于线程同步还适用于进程间同步,这是用户模式下的同步所不具备的,而且内核模式下同步在等待触发过程中是可以指定等待时间,这也是用户模式下同步所缺乏的。
    这篇,我用内核模式下的同步机制实现了之前写的读写同步,使用的是互斥量和信号量,代码为:
#include "stdafx.h"  
#include <windows.h>  

#define MAX_NUM      40  
#define MAX_THREAD   10   
static int g_array[MAX_NUM];
volatile int g_num_gen = 0;
volatile int g_count = 0;
static int g_stop = 0;
HANDLE g_hMutex;
HANDLE g_hSem_full;
HANDLE g_hSem_empty;
HANDLE g_hArray_full[2];
HANDLE g_hArray_empty[2];

LRESULT WINAPI WriteThread(PVOID arg)
{
	while (!g_stop){
		WaitForMultipleObjects(2, g_hArray_empty, TRUE, INFINITE);
		if (g_stop){
			break;
		}
		if (ReleaseSemaphore(g_hSem_full, 1, NULL)){/* 释放一个资源 */
			g_array[g_count++] = g_num_gen++;
			printf("write %d count=%d tid=%lu\n", g_array[g_count - 1], g_count, GetCurrentThreadId());
		}
		else{
			printf("Buffer is full\n");
		}
		ReleaseMutex(g_hMutex);
		Sleep(500);
	}

	ReleaseMutex(g_hMutex);
	ReleaseSemaphore(g_hSem_full, MAX_THREAD, NULL);
	return 0;
}

LRESULT WINAPI ReadThread(PVOID arg)
{
	while (!g_stop){
		WaitForMultipleObjects(2, g_hArray_full, TRUE, INFINITE);
		if (g_stop){
			break;
		}
		ReleaseSemaphore(g_hSem_empty, 1, NULL);
		printf("read %d count=%d tid=%lu\n", g_array[g_count-1], g_count, GetCurrentThreadId());
		g_count--;
		ReleaseMutex(g_hMutex);
		Sleep(500);
	}
	ReleaseSemaphore(g_hSem_empty, MAX_THREAD, NULL);
	ReleaseMutex(g_hMutex);
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hThreadArray[MAX_THREAD];
	g_hMutex = CreateMutex(NULL, FALSE, NULL);
	g_hSem_full = CreateSemaphore(NULL, 0, MAX_NUM, NULL);
	g_hSem_empty = CreateSemaphore(NULL, MAX_NUM, MAX_NUM, NULL);
	g_hArray_full[0] = g_hMutex;
	g_hArray_full[1] = g_hSem_full;

	g_hArray_empty[0] = g_hMutex;
	g_hArray_empty[1] = g_hSem_empty;

	/* 开启写线程 */
	for (int i = 0; i<6; i++){
		hThreadArray[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteThread, NULL, 0, NULL);
	}
	/* 开启读线程 */
	for (int i = 6; i<MAX_THREAD; i++) {
		hThreadArray[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadThread, NULL, 0, NULL);
	}

	getchar();
	g_stop = 1;
	WaitForMultipleObjects(MAX_THREAD, hThreadArray, TRUE, INFINITE);
	for (int i = 0; i<10; i++){
		CloseHandle(hThreadArray[i]);
	}
	CloseHandle(g_hMutex);
	CloseHandle(g_hSem_full);
	CloseHandle(g_hSem_empty);

	printf("All threads exit!\n");
	return 0;
}


猜你喜欢

转载自blog.csdn.net/dailongjian2008/article/details/51968593
今日推荐