Win32_3-线程控制--事件&信号量
程序员文章站
2022-06-04 21:47:42
...
事件
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性 NULL时为系统默认
BOOL bManualReset, // TRUE 通过调用ResetEvent将事件对象标记为未通知
BOOL bInitialState, // TRUE 已通知状态 FALSE未通知状态
LPCTSTR lpName // 对象名称 以NULL结尾的字符串
);
控制事件
BOOL SetEvent(HANDLE hEvent);
实例代码
HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
HWND hEdit4;
HANDLE hThread1;
HANDLE hThread2;
HANDLE hThread3;
HANDLE hThread4;
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
//创建事件
//默认安全属性 手动设置未通知状态(TRUE) 初始状态未通知 没有名字
g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
HANDLE hThread[3];
//创建3个线程
hThread[0] = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
hThread[1] = ::CreateThread(NULL, 0, ThreadProc3, NULL, 0, NULL);
hThread[2] = ::CreateThread(NULL, 0, ThreadProc4, NULL, 0, NULL);
//设置文本框的值
SetWindowText(hEdit1, "1000");
//设置事件为已通知
SetEvent(g_hEvent);
//等待线程结束 销毁内核对象
WaitForMultipleObjects(3, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
CloseHandle(hThread[2]);
CloseHandle(g_hEvent);
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
TCHAR szBuffer[10] = { 0 };
//当事件变成已通知时
WaitForSingleObject(g_hEvent, INFINITE);
//读取内容
GetWindowText(hEdit1, szBuffer, 10);
SetWindowText(hEdit2, szBuffer);
return 0;
}
DWORD WINAPI ThreadProc3(LPVOID lpParameter)
{
TCHAR szBuffer[10] = { 0 };
//当事件变成已通知时
WaitForSingleObject(g_hEvent, INFINITE);
//读取内容
GetWindowText(hEdit1, szBuffer, 10);
SetWindowText(hEdit3, szBuffer);
return 0;
}
DWORD WINAPI ThreadProc4(LPVOID lpParameter)
{
TCHAR szBuffer[10] = { 0 };
//当事件变成已通知时
WaitForSingleObject(g_hEvent, INFINITE);
//读取内容
GetWindowText(hEdit1, szBuffer, 10);
SetWindowText(hEdit4, szBuffer);
return 0;
}
事件达到线程同步
线程同步
//事件和临界区
HANDLE g_hSet, g_hClear;
int g_Max = 10;
int g_Number = 0;
//生产者线程函数
DWORD WINAPI ThreadProduct(LPVOID pM)
{
for (int i = 0; i < g_Max; i++)
{
WaitForSingleObject(g_hSet, INFINITE);
g_Number = 1;
DWORD id = GetCurrentThreadId();
printf("生产者%d将数据%d放入缓冲区\n", id, g_Number);
SetEvent(g_hClear);
}
return 0;
}
//消费者线程函数
DWORD WINAPI ThreadConsumer(LPVOID pM)
{
for (int i = 0; i < g_Max; i++)
{
WaitForSingleObject(g_hClear, INFINITE);
g_Number = 0;
DWORD id = GetCurrentThreadId();
printf("----消费者%d将数据%d放入缓冲区\n", id, g_Number);
SetEvent(g_hSet);
}
return 0;
}
int main(int argc, char* argv[])
{
HANDLE hThread[2];
g_hSet = CreateEvent(NULL, FALSE, TRUE, NULL);
g_hClear = CreateEvent(NULL, FALSE, FALSE, NULL);
hThread[0] = ::CreateThread(NULL, 0, ThreadProduct, NULL, 0, NULL);
hThread[1] = ::CreateThread(NULL, 0, ThreadConsumer, NULL, 0, NULL);
WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
//销毁
CloseHandle(g_hSet);
CloseHandle(g_hClear);
return 0;
}
信号量
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, //安全控制,一般直接传入NULL。
LONG lInitialCount, //初始资源数量。0时不发送信号
LONG lMaximumCount, //最大并发数量。lInitialCount<=lMaximumCount
LPCTSTR lpName //信号量的名称,传入NULL表示匿名信号量
);
#include "stdafx.h"
#include "resource.h"
HANDLE hSemaphore;
HANDLE hThread[3];
HWND hEditSet;
HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
TCHAR szBuffer[10];
DWORD dwTimmer = 0;
WaitForSingleObject(hSemaphore, INFINITE);
while (dwTimmer < 100)
{
Sleep(100);
memset(szBuffer, 0, 10);
GetWindowText(hEdit1, szBuffer, 10);
sscanf(szBuffer, "%d", &dwTimmer);
dwTimmer++;
memset(szBuffer, 0, 10);
sprintf(szBuffer, "%d", dwTimmer);
SetWindowText(hEdit1, szBuffer);
}
ReleaseSemaphore(hSemaphore, 1, NULL);
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
TCHAR szBuffer[10];
DWORD dwTimmer = 0;
WaitForSingleObject(hSemaphore, INFINITE);
while (dwTimmer < 100)
{
Sleep(100);
memset(szBuffer, 0, 10);
GetWindowText(hEdit2, szBuffer, 10);
sscanf(szBuffer, "%d", &dwTimmer);
dwTimmer++;
memset(szBuffer, 0, 10);
sprintf(szBuffer, "%d", dwTimmer);
SetWindowText(hEdit2, szBuffer);
}
ReleaseSemaphore(hSemaphore, 1, NULL);
return 0;
}
DWORD WINAPI ThreadProc3(LPVOID lpParameter)
{
TCHAR szBuffer[10];
DWORD dwTimmer = 0;
WaitForSingleObject(hSemaphore, INFINITE);
while (dwTimmer < 100)
{
Sleep(100);
memset(szBuffer, 0, 10);
GetWindowText(hEdit3, szBuffer, 10);
sscanf(szBuffer, "%d", &dwTimmer);
dwTimmer++;
memset(szBuffer, 0, 10);
sprintf(szBuffer, "%d", dwTimmer);
SetWindowText(hEdit3, szBuffer);
}
ReleaseSemaphore(hSemaphore, 1, NULL);
return 0;
}
DWORD WINAPI ThreadBegin(LPVOID lpParameter)
{
TCHAR szBuffer[10];
DWORD dwMoney = 0;
hSemaphore = CreateSemaphore(NULL, 0, 3, NULL);
hThread[0] = ::CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
hThread[1] = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
hThread[2] = ::CreateThread(NULL, 0, ThreadProc3, NULL, 0, NULL);
//开始准备红包
while (dwMoney < 1000)
{
memset(szBuffer, 0, 10);
GetWindowText(hEditSet, szBuffer, 10);
sscanf(szBuffer, "%d", &dwMoney);
dwMoney++;
memset(szBuffer, 0, 10);
sprintf(szBuffer, "%d", dwMoney);
SetWindowText(hEditSet, szBuffer);
}
ReleaseSemaphore(hSemaphore, 2, NULL);
::WaitForMultipleObjects(3, hThread, TRUE, INFINITE);
::CloseHandle(hSemaphore);
return 0;
}
BOOL CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL bRet = FALSE;
switch (uMsg)
{
case WM_CLOSE:
{
EndDialog(hDlg, 0);
break;
}
case WM_INITDIALOG:
{
hEditSet = GetDlgItem(hDlg, IDC_EDIT_SET);
hEdit1 = GetDlgItem(hDlg, IDC_EDIT_1);
hEdit2 = GetDlgItem(hDlg, IDC_EDIT_2);
hEdit3 = GetDlgItem(hDlg, IDC_EDIT_3);
SetWindowText(hEditSet, "0");
SetWindowText(hEdit1, "0");
SetWindowText(hEdit2, "0");
SetWindowText(hEdit3, "0");
break;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BUTTON_BEGIN:
{
CreateThread(NULL, 0, ThreadBegin, NULL, 0, NULL);
return TRUE;
}
}
break;
}
return bRet;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_MAIN), NULL, MainDlgProc);
return 0;
}
推荐阅读