信号量


创建信号量

HANDLE CreateSemaphore(

LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

LONG lInitialCount,

LONG lMaximumCount,

LPCTSTR lpName

);

函数说明:

第一个参数表示安全控制,一般直接传入NULL。

第二个参数表示初始资源数量。0时不发送信号

第三个参数表示最大并发数量。lInitialCount<=lMaximumCount

第四个参数表示信号量的名称,传入NULL表示匿名信号量。


打开信号量

HANDLE OpenSemaphore(

DWORD dwDesiredAccess,

BOOL bInheritHandle,

LPCTSTR lpName

);

函数说明:

第一个参数表示访问权限,对一般传入SEMAPHORE_ALL_ACCESS。详细解释可以查看MSDN文档。

第二个参数表示信号量句柄继承性,一般传入FALSE即可。

第三个参数表示名称,不同进程中的各线程可以通过名称来确保它们访问同一个信号量。


递增信号量的当前资源计数


BOOL ReleaseSemaphore(

HANDLE hSemaphore,

LONG lReleaseCount,

LPLONG lpPreviousCount

);

函数说明:

第一个参数是信号量的句柄。

第二个参数表示增加个数,必须大于0且不超过最大资源数量。

第三个参数返回当前资源数量的原始值,设为NULL表示不需要传出。

注:没有一个函数可以用来查询信标的当前资源数量的值


信号量的清理与销毁

CloseHandle()

以下是吃字符程序

// eat.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include<stdio.h>
#include<string.h>
#include"resource.h"

HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
HWND hEdit4;
HWND hEdit5;
HWND hEdit6;
HWND hEdit7;
HWND h[4];
CRITICAL_SECTION cs;
HANDLE hSemaphore;
char arr1 = 0, arr2 = 0;
char arr[10] = {0};
int index = 0;

DWORD WINAPI ProcThread2(LPVOID lpParameter)
{
char str[2] = {0};
char string[10] = {0};
int i = (int)lpParameter;
WaitForSingleObject(hSemaphore, INFINITE);
while(index < strlen(arr))
{
EnterCriticalSection(&cs);
Sleep(1000);
if(arr1 != 0)
{
GetWindowText(h[i], string, 10);
sprintf(str, "%c", arr1);
arr1 = 0;
strcat(string, str);
SetWindowText(h[i], string);
}else
{
GetWindowText(h[i], string, 10);
sprintf(str, "%c", arr2);
arr2 = 0;
strcat(string, str);
SetWindowText(h[i], string);
}
ReleaseSemaphore(hSemaphore, 2, NULL);
LeaveCriticalSection(&cs);
}

return 0;
}

DWORD WINAPI ProcThread(LPVOID lpParameter)
{
HANDLE hThreadArr[4];
char array[2] = {0};

hSemaphore = CreateSemaphore(NULL, 0, 2, NULL);

hThreadArr[0] = ::CreateThread(NULL, 0, ProcThread2, (void *)0, 0, NULL);
hThreadArr[1] = ::CreateThread(NULL, 0, ProcThread2, (void *)1, 0, NULL);
hThreadArr[2] = ::CreateThread(NULL, 0, ProcThread2, (void *)2, 0, NULL);
hThreadArr[3] = ::CreateThread(NULL, 0, ProcThread2, (void *)3, 0, NULL);

GetWindowText(hEdit1, arr, 10);
while(index < strlen(arr))
{
EnterCriticalSection(&cs);
arr1 = arr[index++];
sprintf(array, "%c", arr1);
SetWindowText(hEdit2, array);
Sleep(1000);
if(arr1 != 0)
{
arr2 = arr[index++];
sprintf(array, "%c", arr2);
SetWindowText(hEdit3, array);
}
LeaveCriticalSection(&cs);
ReleaseSemaphore(hSemaphore, 2, NULL);
}


WaitForMultipleObjects(4, hThreadArr, TRUE, INFINITE);
CloseHandle(hSemaphore);
CloseHandle(hThreadArr[0]);
CloseHandle(hThreadArr[1]);
CloseHandle(hThreadArr[2]);
CloseHandle(hThreadArr[3]);
return 0;
}


BOOL CALLBACK Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
DeleteCriticalSection(&cs);
EndDialog(hwnd, 0);
break;
case WM_INITDIALOG:
hEdit1 = GetDlgItem(hwnd, IDC_EDIT1);
hEdit2 = GetDlgItem(hwnd, IDC_EDIT2);
hEdit3 = GetDlgItem(hwnd, IDC_EDIT3);
hEdit4 = GetDlgItem(hwnd, IDC_EDIT4);
hEdit5 = GetDlgItem(hwnd, IDC_EDIT5);
hEdit6 = GetDlgItem(hwnd, IDC_EDIT6);
hEdit7 = GetDlgItem(hwnd, IDC_EDIT7);
h[0] = hEdit4;
h[1] = hEdit5;
h[2] = hEdit6;
h[3] = hEdit7;
SetWindowText(hEdit4, "");
SetWindowText(hEdit5, "");
SetWindowText(hEdit6, "");
SetWindowText(hEdit7, "");
InitializeCriticalSection(&cs);
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BUTTON1:

HANDLE hThread = ::CreateThread(NULL, 0, ProcThread, NULL, 0, NULL);

CloseHandle(hThread);
return TRUE;
}
break;
}
return FALSE;
}

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Proc);
return 0;
}

原文地址:https://www.cnblogs.com/Lu3ky-Athena/p/13732489.html