线程同步——内核对象实现线程同步——信号量

  1 /*
  2
  3 信号量内核对象
  4     信号量与其它内核量相同,包含一个使用计数,除此之外还包含两个量。
  5     一个最大资源计数和一个当前资源计数。
  6     信号量规则如下:
  7     如果当前资源计数大于0,那么信号量处于触发状态。
  8     如果当前资源计数等于0,那么信号量处于未触发状态。
  9     系统绝不会让当前资源计数变为负数。
 10     当前资源计数绝不会大于最大资源计数。
 11
 12     下面我们看一下信号量的创建函数
 13     HANDLE  CreateSemaphore(
 14     LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
 15     LONG lInitialCount,
 16     LONG lMaximumCount,
 17     LPCSTR lpName );
 18 第一、四个参数同其他内核对象一样,就不过多介绍了。
 19     第三个参数lInitialCount为当前资源计数,第四个参数lMaximumCount为最大资源计数
 20
 21     线程通过调用ReleaseSemaphore,来增加当前资源计数。
 22     下面看ReleaseSemaphore函数:
 23
 24     BOOL ReleaseSemaphore(
 25     HANDLE hSemaphore,
 26     LONG lReleaseCount,
 27     LPLONG lpPreviousCount ) ;
 28 第一个参数hSemaphore,为信号量句柄,第二个参数lReleaseCount为增加资源数
 29     第三个参数lpPreviousCount为返回当前资源计数,一般传入 NULL。
 30
 31     关于信号量需要注意的是,在递减当前资源计数时是以原子方式进行的。
 32     但是递减完后,其它线程便可以访问资源,在这个时候先前线程也许并未结束,
 33     所以信号量并不互斥,主要用于控制访问次数或者创建的线程数。
 34
 35 下面我们看一下使用步骤:
 36
 37
 38 1)
 39 //定义一个信号量
 40 HANDLE g_hSemaphore  ;
 41 2)
 42 //创建一个信号量内核对象
 43 g_hSemaphore = CreateSemaphore(NULL,0,5,NULL);
 44 3)
 45 //增加信号量当前资源数
 46 ReleaseSemaphore(g_hSemaphore,5,NULL);
 47 4)
 48 //在线程函数中调用
 49 DWORD WINAPI ThreadFunOne(PVOID pvParam)
 50 {
 51     while(1)
 52     {
 53         WaitForSingleObject(g_hSemaphore,INFINITE);
 54         g_x++;
 55         cout<<"我是ThreadFunOne:"<<g_x<<endl;
 56     }
 57     return 0;
 58 }
 59
 60 */
 61
 62 #include "windows.h"
 63 #include "iostream"
 64 using namespace std;
 65 long g_x = 0 ;
 66
 67 //定义一个信号量
 68 HANDLE g_hSemaphore  ;
 69 //定义线程函数1
 70 DWORD WINAPI ThreadFunOne(PVOID pvParam) ;
 71
 72 //定义线程函数2
 73 DWORD WINAPI ThreadFunTwo(PVOID pvParam);
 74
 75 int main()
 76 {
 77
 78     //创建一个信号量内核对象
 79     g_hSemaphore = CreateSemaphore(NULL,0,5,NULL);
 80
 81     //增加信号量当前资源数
 82     ReleaseSemaphore(g_hSemaphore,5,NULL);
 83
 84     //创建线程1
 85     HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL);
 86     CloseHandle(hThreadOne);
 87
 88     //创建线程2
 89     HANDLE hThreadTwo = CreateThread(NULL,0,ThreadFunTwo,0,0,NULL);
 90     CloseHandle(hThreadTwo);
 91
 92     getchar();
 93     cout<<g_x<<endl;
 94     return 0 ;
 95 }
 96
 97 DWORD WINAPI ThreadFunOne(PVOID pvParam)
 98 {
 99     while(1)
100     {
101         WaitForSingleObject(g_hSemaphore,INFINITE);
102         g_x++;
103         cout<<"我是ThreadFunOne:"<<g_x<<endl;
104     }
105     return 0;
106 }
107
108 DWORD WINAPI ThreadFunTwo(PVOID pvParam)
109 {
110     while (1)
111     {
112         WaitForSingleObject(g_hSemaphore,INFINITE);
113         g_x++;
114         cout<<"我是ThreadFunTwo:"<<g_x<<endl;
115     }
116     return 0;
117 }

线程同步——内核对象实现线程同步——信号量

时间: 2024-12-25 19:56:28

线程同步——内核对象实现线程同步——信号量的相关文章

线程同步——内核对象实现线程同步——等待函数

1 对于内核对象实现线程同步,不得不提三点: 2 1)大多数内核对象既有触发也有未触发两个状态 3 比如:进程.线程.作业.文件流.事件.可等待的计时器.信号量.互斥量 4 2)等待函数:等待函数使线程自愿进入等待状态,直到指定的内核对象变为触发状态为止, 5 说道等待我们最喜欢不过了,因为这样不会浪费我们宝贵的CPU时间. 6 3)对于自动重置对象来说,当对象被触发时,函数会自动检测到(手动重置对象为触发是,函数也能检测到), 7 并开始执行,但是在函数会在返回之前使事件变为非触发状态. 8

线程同步——内核对象实现线程同步——事件内核对象

1 事件内核对象 2 3 事件类型对象有两种不同类型,手动重置和自动重置 4 手动重置:当一个手动重置对象被触发时候,等待该对象的所有线程变为可调度. 5 自动重置:当一个自动重置对象被触发时,只有一个等待该事件的线程会变为可调度 6 7 下面是一个创建事件内核对象的函数: 8 HANDLE CreateEvent( 9 LPSECURITY_ATTRIBUTES lpEventAttributes, 10 BOOL bManualReset, 11 BOOL bInitialState, 12

线程同步——内核对象实现线程同步——可等待计时器内核对象

1 可等待计时器 2 可等待计时器是这样一种内核对象,他们会在某个指定的时间触发或每隔一段时间触发一次. 5 下面我们来介绍一下创建可等待计时器函数: 6 7 HANDLE CreateWaitableTimer( 8 LPSECURITY_ATTRIBUTES lpTimerAttributes, 9 BOOL bManualReset, 10 LPCSTR lpTimerName ); 11 第一.三个参数我想我也不用介绍了哈,这是创建内核对象基本都会有的参数. 12 第二个参数bManua

Win32线程同步内核对象的比较

X86处理器上用户层到内核层的转换要花费600个CPU指令周期 临界区(关键代码段)不是内核对象 但当访问被占用的资源时会使用内核资源 功能同互斥但不可跨进程 (以上引用自:http://www.dewen.org/q/9561) WIN32内核对象都是由HANDLE操控 信号量(Semaphore) wait函数族使访问计数递减 当且仅当访问计数0时无信号 ReleaseSemaphore递增访问计数 互斥(Mutex) 有且仅有1个访问计数的信号量(二元信号量binary semaphore

线程与内核对象的同步

线程与内核对象的同步内核对象可以处于已通知或未通知状体进程,线程,作业,文件,控制台输入,文件修改,事件,可等待定时器 等待函数DWORD WaitForSingleObject(HANDLE hobject, DWORD dwMilliseconds); 同时查看若干个内核对象已通知状体DWORD WaitForMultipleObjects(DWORD dwCount,CONST HANDLE* phObjects,BOOL fWaitAll,DWORD dwMilliseconds);dw

第9章 用内核对象进行线程同步(3)_信号量(semaphore)、互斥量(mutex)

9.5 信号量内核对象(Semaphore) (1)信号量的组成 ①计数器:该内核对象被使用的次数 ②最大资源数量:标识信号量可以控制的最大资源数量(带符号的32位) ③当前资源数量:标识当前可用资源的数量(带符号的32位) (2)信号量的使用规则 ①如果当前资源计数>0,那么信号量处于触发状态,表示有可用资源. ②如果当前资源计数=0,那么信号量处于未触发状态,表示没有可用资源. ③系统绝不会让当前资源计数变为负数: ④当前资源计数绝对不会大于最大资源计数 (3)信号量的用法 (4)相关函数

第9章 用内核对象进行线程同步(4)_死锁(DeadLock)及其他

9.7 线程同步对象速查表 对象 何时处于未触发状态 何时处于触发状态 成功等待的副作用 进程 进程仍在运行的时候 进程终止的时(ExitProcess.TerminateProcess) 没有 线程 线程仍在运行的时候 线程终止的时候(ExitThread.TermimateThread) 没有 作业 作业尚未超时的时候 作业超时的时候 没有 文件 有待处理的I/O请求的时候 I/O请求完成的时候 没有 控制台输入 没有输入的时候 有输入的时候 没有 文件变更通知 文件没有变更的时候 文件系统

Windows API学习---线程与内核对象的同步

前言 若干种内核对象,包括进程,线程和作业.可以将所有这些内核对象用于同步目的.对于线程同步来说,这些内核对象中的每种对象都可以说是处于已通知或未通知的状态之中.这种状态的切换是由Microsoft为每个对象建立的一套规则来决定的.例如,进程内核对象总是在未通知状态中创建的.当进程终止运行时,操作系统自动使该进程的内核对象处于已通知状态.一旦进程内核对象得到通知,它将永远保持这种状态,它的状态永远不会改为未通知状态. 当进程正在运行的时候,进程内核对象处于未通知状态,当进程终止运行的时候,它就变

内核对象进行线程同步

前言: 具体的可等待的内核对象有: 进程,线程,作业,文件以及控制台的标准输入流/输出流/错误流,事件,可等待的计时器,信号量,互斥量. 等待函数: DWORD WaitForSingleObject( HANDLE hObject,//用来标识要等待的内核对象 DWORD dwMilliseconds);//等待的时间 DWORD WaitForMultipleObjects( DWORD dwCount,//函数检查的内核对象的数量(最大为MAXIMUM_WAIT_OBJECTS) CONS