您的位置:首页 > 编程语言 > C语言/C++

C++ 信号量 多线程同步互斥

2016-05-17 11:11 375 查看
信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程 最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。在用CreateSemaphore()创建信号量 时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数 就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目, 不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可 用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。

PV操作及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用共享资源的进程数。

P操作 申请资源:

(1)S减1;

(2)若S减1后仍大于等于零,则进程继续执行;

(3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转入进程调度。

V操作 释放资源:

(1)S加1;

(2)若相加结果大于零,则进程继续执行;

(3)若相加结果小于等于零,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转入进程调度。

信号量包含的几个操作原语:

CreateSemaphore() 创建一个信号量

OpenSemaphore() 打开一个信号量

ReleaseSemaphore() 释放信号量

WaitForSingleObject() 等待信号量

#include <Windows.h>
#include <stdio.h>

HANDLE hSemaphore = NULL;
const char* strSemaphoreName = "MySemaphore";
const int threads_num = 50;
HANDLE Threads[threads_num];
bool bExitThreads = FALSE;

void WINAPI ThreadFun(void* param)
{
printf("线程 %u 开始运行\n", GetCurrentThreadId());
WaitForSingleObject(hSemaphore,INFINITE);
printf("线程 %u 获得信号量,继续运行\n", GetCurrentThreadId());
while(!bExitThreads)
{
Sleep(10);
}
long dwSem = 0;
if (!ReleaseSemaphore(hSemaphore, 1, &dwSem))
{
if (0 == GetLastError())
{
printf("当前可用资源数:20\n");
return;
}
}

printf("当前可用资源数:%u\n", dwSem);
}

void creatThreads()
{
DWORD dwThreadID = 0;
for (int i =0; i < threads_num; ++i)
{
Threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFun, NULL, 0, &dwThreadID);
if (!Threads[i])
{
printf("创建线程失败!\n");
}
printf("线程 %u 创建成功\n", dwThreadID);
}
}

void  main()
{
hSemaphore = CreateSemaphoreA(NULL, 0, 20, strSemaphoreName);
if(NULL == (hSemaphore = OpenSemaphoreA(SEMAPHORE_MODIFY_STATE , FALSE, strSemaphoreName)))
{
printf("打开信号量对象失败 , 错误ID:%u\n", GetLastError());
return;
}

creatThreads();
bExitThreads = true;
WaitForMultipleObjects(threads_num, Threads, TRUE, INFINITE);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: