多线程之信号量 Samephore

 信号量相当于一个计数器,记录一个共享资源被访问线程的个数;好比有两个或者更多个办事窗口,他们都做同一件事;假设有5个窗口,五个窗口都没人访问的时候计数器为5;有一个窗口被占用计数器减1,为4;全部被占用则计数器为0;这时候其他人想要访问就必须等待占用结束后计数器加1;

HANDLE WINAPI CreateSemaphore(
  __in          LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
  __in          LONG lInitialCount,//初始化计数
  __in          LONG lMaximumCount,//最大计数
  __in          LPCTSTR lpName //名称
);
BOOL WINAPI ReleaseSemaphore(
  __in          HANDLE hSemaphore, //信号量句柄
  __in          LONG lReleaseCount,//释放个数
  __out         LPLONG lpPreviousCount//
);

实例:

写一个可多读多写的队列

#pragma once
#include <stdlib.h>
#include <Windows.h>

#define  G_MAX   10  // 信号量最多同时访问线程数量
#define  MAXTHREAD   20 //读写线程个数


//模板不支持将声明与实现分两个文件实现;  会出错 link  2019 找不到实现文件
template <class T>
class CMyDeque
{
public:
	CMyDeque();
	~CMyDeque();
	void PushValue(const T &element);
	T PopValue();
private:

	HANDLE  g_Samephore_R;  // 读信号量
	HANDLE  g_Samephore_W; // 写信号量

	//HANDLE  h_Read[MAXTHREAD];
	//HANDLE  h_Write[MAXTHREAD];

	int nDequeLen; // 队列长度  默认为1024
	int nBack;  //队尾

	T * m_data;
};

template <class T>
CMyDeque<T>::CMyDeque()
{
	nDequeLen = 1024;
	nBack = 0;
	m_data = new T[1024];

	g_Samephore_R = CreateSemaphore(NULL, G_MAX, G_MAX, L"ReadSem");
	g_Samephore_W = CreateSemaphore(NULL, 1, 1, L"WriteSem");
}

template <class T>
CMyDeque<T>::~CMyDeque()
{
	/*
	for (int i = 0; i < MAXTHREAD; i++)
	{
	CloseHandle(h_Read[i]);
	CloseHandle(h_Write[i]);
	}
	*/
	CloseHandle(g_Samephore_W);
	CloseHandle(g_Samephore_R);
}

template <class T>
void CMyDeque<T>::PushValue(const T &element)
{
	if ((nBack+1) % nDequeLen == 0)
	{
		T *temp = m_data;
		nDequeLen = nDequeLen * 2;
		m_data = new T[nDequeLen];
		for (int i = 0; i < nBack; i++)
		{
			m_data[i] = temp[i];
		}
	}

	WaitForSingleObject(g_Samephore_W, INFINITE);
	m_data[nBack] = element;
	nBack++;
	ReleaseSemaphore(g_Samephore_W, 1, NULL);
}

template <class T>
T CMyDeque<T>::PopValue()
{
	WaitForSingleObject(g_Samephore_R, INFINITE);
	WaitForSingleObject(g_Samephore_W, INFINITE);
	T result = m_data[nBack-1];
	ReleaseSemaphore(g_Samephore_W, 1, NULL);
	ReleaseSemaphore(g_Samephore_R, 1, NULL);
	return result;
}
// MutiRWDeque.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "CMutiWRDeque.h"
#include <thread>
#include <mutex>

CMyDeque<int> mydeque;
static int i = 0;

std::mutex  mutexlock;

void read()
{
	while (i<100)
	{
		cout << "线程" << GetCurrentThreadId() << "读出数据" << mydeque.PopValue() << endl;
		Sleep(1000);
	}
}

void write()
{
	while (i<100)
	{
		mutexlock.lock();
		i++;
		mydeque.PushValue(i); 
		cout << "线程" << GetCurrentThreadId() << "写入数据" << i << endl;
		mutexlock.unlock();
		Sleep(400);
	}
}

int main()
{
	thread  t1(write);
	thread  t2(write);
	thread  t3(write);
	thread  t4(write);
	thread  t5(write);
	thread  t6(write);
	thread  t7(read);
	thread  t8(read);
	thread  t9(read);
	thread  t10(read);
	thread  t11(read);
	thread  t12(read);

	while (1)
	{
	};
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/QWERDF10010/article/details/83305602