线程同步(1) - 用户模式下的线程同步
来源:互联网 发布:程序员健康指南 编辑:程序博客网 时间:2024/05/29 19:33
(1) 用户模式的等待
DWORD WaitForSingleObject(
HANDLE hHandle, // handle to object to wait for
DWORD dwMilliseconds // time-out interval in milliseconds
);
DWORD WaitForMultipleObjects(
DWORD
nCount
,
// number of handles in the handle array
CONST HANDLE
*lpHandles
,
// pointer to the object-handle array
BOOL
fWaitAll
,
// wait flag
DWORD
dwMilliseconds
// time-out interval in milliseconds
);
(2) 用户模式的事件
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES
lpEventAttributes
,
// pointer to security attributes
BOOL
bManualReset
,
// flag for manual-reset event
BOOL
bInitialState
,
// flag for initial state
LPCTSTR
lpName
// pointer to event-object name
);
示例代码:
#include <stdio.h>
#include <process.h>
#include <windows.h>
UINT WINAPI ThreadProc( LPVOID lpParameter )
{
printf("Enter Second Thread!\n");
HANDLE hEvent = *(PHANDLE)lpParameter;
Sleep(1000);
printf("Leave Second Thread!\n");
//激发事件
SetEvent(hEvent);
return 0;
}
int main(void)
{
printf("Enter Main Thread!\n");
//定义一个自动重置的,未激发的事件对象
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, &hEvent, 0, NULL);
//等待该事件激发
WaitForSingleObject(hEvent, INFINITE);
printf("Leave Main Thread!\n");
return 0;
}
(3) 用户模式的信号灯
信号灯内部有个计数器,可以理解信号灯内部有N个灯泡,如果有一个灯泡亮着,就代表信号灯处于激发状态,如果全部熄灭,就代表信号灯处于未激发状态。
创建信号灯:
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES
lpSemaphoreAttributes
,
// pointer to security attributes
LONG
lInitialCount
,
// initial count
LONG
lMaximumCount
,
// maximum count
LPCTSTR
lpName
// pointer to semaphore-object name
);
增加信号灯的计数器:
BOOL ReleaseSemaphore(
HANDLE
hSemaphore
,
// handle to the semaphore object
LONG
lReleaseCount
,
// amount to add to current count
LPLONG
lpPreviousCount
// address of previous count
);
对信号灯执行一次等待操作,就会减少一个计数,就相当于熄灭一个灯泡。当计数为0时,也就是所有灯泡都熄灭时,当前线程进入睡眠状态,直到信号灯变成激发状态或者超时。
示例代码:
#include <windows.h>
#include <stdio.h>
#include <process.h>
UINT WINAPI ThreadProc(LPVOID lpParam)
{
printf("Enter Second Thread!\n");
HANDLE hSemaphore = *(PHANDLE)lpParam;
Sleep(5000);
printf("Leave Second Thread!\n");
//将信号灯计数加1,使之成为激发状态
ReleaseSemaphore(hSemaphore, 1, NULL);
return 0;
}
int main(void)
{
printf("Enter Main Thread!\n");
//创建信号灯
HANDLE hSemaphore = CreateSemaphore(NULL, 2, 2, NULL);
//此时信号灯计数为2,处于激发状态
WaitForSingleObject(hSemaphore, INFINITE);
//此时信号灯计数为1,处于激发状态
WaitForSingleObject(hSemaphore, INFINITE);
//创建新线程
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, &hSemaphore, 0, NULL);
//此时信号灯计数为0,处于未激发状态,为了等待信号灯,线程被挂起
WaitForSingleObject(hSemaphore, INFINITE);
printf("Leave Main Thread!\n");
return 0;
}
(4) 用户模式的互斥体
获得了互斥体之后,同一个线程中可以递归获得互斥体。所谓递归获得互斥体就是得到互斥体的线程还可以再次获得这个互斥体,或者说互斥体对于已经获得互斥体的线程不产生
”互斥”关系。
创建互斥体:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES
lpMutexAttributes
,
// pointer to security attributes
BOOL
bInitialOwner
,
// flag for initial ownership
LPCTSTR
lpName
// pointer to mutex-object name
);
释放互斥体:
BOOL ReleaseMutex(
HANDLE hMutex // handle to mutex object
);
示例代码:
#include <windows.h>
#include <process.h>
#include <stdio.h>
UINT WINAPI ThreadProc1(LPVOID lparam)
{
HANDLE hMutex = *(PHANDLE)lparam;
//等待互斥体
WaitForSingleObject(hMutex, INFINITE);
//对于同一个线程,已经获得了互斥体,还可以多次获取
WaitForSingleObject(hMutex, INFINITE);
printf("Enter Thread1!\n");
Sleep(2000);
printf("Leave Thread1!\n");
//释放互斥体
ReleaseMutex(hMutex);
return 0;
}
UINT WINAPI ThreadProc2(LPVOID lparam)
{
HANDLE hMutex = *(PHANDLE)lparam;
WaitForSingleObject(hMutex, INFINITE);
printf("Enter Thread2!\n");
Sleep(2000);
printf("Leave Thread2!\n");
ReleaseMutex(hMutex);
return 0;
}
int main(void)
{
printf("Enter Main Thread!\n");
//创建互斥体
HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);
HANDLE hThread1 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc1, &hMutex, 0, NULL);
HANDLE hThread2 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc2, &hMutex, 0, NULL);
Sleep(6000);
printf("Leave Main Thread!\n");
return 0;
}
(5) 等待线程完成
还有一种同步对象,就是线程对象。每个线程同样有两个状态,激发状态和未激发状态。当线程在运行中的时候,是未激发状态。当线程终止后,线程处于激发状态。可以用WaitFor*函数对线程句柄进行等待。
示例代码:
#include <windows.h>
#include <stdio.h>
#include <process.h>
UINT WINAPI ThreadProc(LPVOID lpParam)
{
printf("Enter ThreadProc!\n");
Sleep(5000);
printf("Leave ThreadProc!\n");
return 0;
}
int main(void)
{
//创建两个字线程
HANDLE hThread1 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, NULL);
HANDLE hThread2 = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, NULL);
//主线程等待两个字线程结束
HANDLE hThread[2] = {hThread1, hThread2};
WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
return 0;
}
- 线程同步(1) - 用户模式下的线程同步
- 线程同步(1) - 用户模式下的线程同步
- Windows线程同步—用户模式下的线程同步
- 线程同步——用户模式下的线程同步
- 用户模式下线程同步
- 用户模式下线程同步
- 用户模式下的线程同步
- 用户模式下的线程同步
- Chapter08-用户模式下的线程同步
- 用户模式下的线程同步
- 八、 用户模式下的线程同步
- 八 用户模式下的线程同步
- 用户模式下的线程同步
- Chapter08-用户模式下的线程同步
- 用户模式下的线程同步
- 用户模式下的线程同步
- windows核心编程-用户模式下的线程同步1
- 用户模式的线程同步
- RSU,是Road Side Unit的英文缩写
- AxureRP7.0教程 部件详解 HTML Button HTML按钮
- Android睡眠唤醒机制--系统架构
- 游戏教程 如何用cocos2d-x3.0做一款塔防 第一篇
- 关于数据仓库几个术语的个人见解
- 线程同步(1) - 用户模式下的线程同步
- android实现蘑菇街购物车动画效果
- android系统源码目录system/framework下各个jar包的用途
- Redis消息通知系统的实现
- CentOs的网络环境配置
- 同一进程下的线程可以共享什么?
- centos6.4 安装jdk7和tomcat7
- 正益王国春:AppCan 为HTML5移动创新与创业而生
- Rainbow的信号 位运算