信号量 Semaphore
信号量也是一个内核对象。
结构:
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, //安全属性
LONG lInitialCount, //可用的资源数量,如线程数量。
LONG lMaximumCount, //最大可用数量
LPCTSTR lpName ); //信号量的名字,NULL为匿名的。
创建:
//创建一个匿名的信号量,初始可用资源数量为0,最大资源数量为3.
HANDLE hSemaphore = Createsemaphore(NULL,0,3,NULL);
使用:
1.主线程创建一个信号量对象(HANDLE hSemaphore = Createsemaphore(NULL,0,3,NULL)); 此处创建一个信号量,但是它没有发信息, WaitForSingleObject(hSemaphore,-1);这个后面的代码就无法执行。
2.想要子线程 WaitForSingleObject(hSemaphore,-1)后面的代码执行,就必须在主线程里面的代码后面,用 ReleaseSemaphore(hSemaphore,1,NULL)函数来增加 1 个资源数量,告诉系统,有一个线程空出来了,可以执行了。
3.子线程等到 hSemaphore 里面有一个资源了,就开始执行WaitForSingleObject(hSemaphore,-1)后面的代码。
代码示例:
点击开始后,最上面的编辑框从0加到100完成后,下面自定义同时2条线程启动,将对应的线程的编辑框也从0加到100,每完成一条线程,就启动新的线程。
vc6代码:
// Read_letter.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include <windows.h>
#include <stdio.h>
HWND Hwnd_ExeHwnd;
HWND hEdit1;
HWND hEdit2;
HWND hEdit3;
HWND hEdit4;
HANDLE hSemaphore;
HANDLE hThread_edit[3];
DWORD WINAPI next_pro1(LPVOID lpParameter)
{
DWORD dwmoney=0;
TCHAR szbuffer[10];
WaitForSingleObject(hSemaphore,-1);
while(dwmoney<100)
{
GetWindowText(hEdit2,szbuffer,10);
sscanf(szbuffer,"%d",&dwmoney);
dwmoney++;
memset(szbuffer,0,10);
sprintf(szbuffer,"%d",dwmoney);
SetWindowText(hEdit2,szbuffer);
Sleep(50);
}
ReleaseSemaphore(hSemaphore,1,NULL);
return 0;
}
DWORD WINAPI next_pro2(LPVOID lpParameter)
{
DWORD dwmoney=0;
TCHAR szbuffer[10];
WaitForSingleObject(hSemaphore,-1);
while(dwmoney<100)
{
GetWindowText(hEdit3,szbuffer,10);
sscanf(szbuffer,"%d",&dwmoney);
dwmoney++;
memset(szbuffer,0,10);
sprintf(szbuffer,"%d",dwmoney);
SetWindowText(hEdit3,szbuffer);
Sleep(50);
}
ReleaseSemaphore(hSemaphore,1,NULL);
return 0;
}
DWORD WINAPI next_pro3(LPVOID lpParameter)
{
DWORD dwmoney=0;
TCHAR szbuffer[10];
WaitForSingleObject(hSemaphore,-1);
while(dwmoney<100)
{
GetWindowText(hEdit4,szbuffer,10);
sscanf(szbuffer,"%d",&dwmoney);
dwmoney++;
memset(szbuffer,0,10);
sprintf(szbuffer,"%d",dwmoney);
SetWindowText(hEdit4,szbuffer);
Sleep(50);
}
ReleaseSemaphore(hSemaphore,1,NULL);
return 0;
}
DWORD WINAPI Begin_pro(LPVOID lpParameter)
{
DWORD dwmoney=0;
TCHAR szbuffer[10];
hSemaphore=CreateSemaphore(NULL,0,3,NULL);
// g_event=CreateEvent(NULL,FALSE,FALSE,"");
hThread_edit[0]=CreateThread(NULL,0,next_pro1,NULL,0,NULL);
hThread_edit[1]=CreateThread(NULL,0,next_pro2,NULL,0,NULL);
hThread_edit[2]=CreateThread(NULL,0,next_pro3,NULL,0,NULL);
//准备红包
while(dwmoney<100)
{
GetWindowText(hEdit1,szbuffer,10);
sscanf(szbuffer,"%d",&dwmoney);
dwmoney++;
memset(szbuffer,0,10);
sprintf(szbuffer,"%d",dwmoney);
SetWindowText(hEdit1,szbuffer);
Sleep(50);
}
ReleaseSemaphore(hSemaphore,2,NULL);
WaitForMultipleObjects(3,hThread_edit,TRUE,-1);
CloseHandle( hThread_edit[0]);
CloseHandle( hThread_edit[1]);
CloseHandle( hThread_edit[2]);
CloseHandle(hSemaphore);
return 0;
}
BOOL CALLBACK MAIN_PROC(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
Hwnd_ExeHwnd=hwndDlg;
switch(uMsg)
{
case WM_CLOSE:
EndDialog(hwndDlg,0);
break;
case WM_INITDIALOG :
hEdit1=GetDlgItem(Hwnd_ExeHwnd,IDC_EDIT1);
hEdit2=GetDlgItem(Hwnd_ExeHwnd,IDC_EDIT2);
hEdit3=GetDlgItem(Hwnd_ExeHwnd,IDC_EDIT3);
hEdit4=GetDlgItem(Hwnd_ExeHwnd,IDC_EDIT4);
SetWindowText(hEdit1,"0");
SetWindowText(hEdit2,"0");
SetWindowText(hEdit3,"0");
SetWindowText(hEdit4,"0");
break;
case WM_COMMAND :
switch(LOWORD(wParam))
{
case IDC_BUTTON_START:
HANDLE hThread_Main=CreateThread(NULL,0,Begin_pro,NULL,0,NULL);
break;
}
break;
}
return FALSE ;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,MAIN_PROC);
return 0;
}