写在前面,这是快餐文章,大侠们尽可一笑而过,对错自辨。
讲到信号,就不得不讲到3种涉众:1. 发信号者;2.传信号者;3.眼巴巴的等着收信号的。
(看官此时嘘我了,书上可没这么讲过,你瞎叨叨啥呢?)
打个比方,超级大乐透摇奖开始了,全国无数财迷(哦,谢特!打拼音的坏处就是经常出现这种情况,把彩民打成财迷了)就是第3种人,眼巴巴的等着最后的数字,在数字没出炉前,尽管他们中有手心冒汗的,哈喇子吧嗒吧嗒流的,眼睛红了紫、紫了绿的,但他他们都有一个共同点,那就是死,也要死在电视机前,决不挪动半步,“等”就一个字!涉众的第2中就是电视媒体了,它们负责传递实时的信息。第1种显然就是超级大乐透摇奖现场乐。一旦摇出大奖,那些等着的人有的抹了抹口水该干吗干吗去了,有的擦了擦汗睡觉去了,中大奖的准备人间蒸发了,中小奖的准备连夜上大拍档了,在农村没啥消遣的就抱老公搂老婆上炕了,看官,您贵干去了呀?
当然. WINDOWS里信号量是不少的,有用于进程内线程同步的、有由于进程间同步的、有临界资源互斥访问同步的,今天,现在,咱只讨论事件信号。先参考平台SDK里的函数,仅供参考,不看也罢。当然,给看官你带来的损失也罢,哈哈!
The CreateEvent function creates or opens a named or unnamed event object.
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
);
The SetEvent function sets the specified event object to the signaled state.
BOOL SetEvent(
HANDLE hEvent
);
The ResetEvent function sets the specified event object to the nonsignaled state.
BOOL ResetEvent(
HANDLE hEvent
);
The WaitForSingleObject function returns when the specified object is in the signaled state or the time-out interval elapses.
To enter an alertable wait state, use the WaitForSingleObjectEx function. To wait for multiple objects, use the WaitForMultipleObjects.
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
以上四个函数是最基本的,面向过程的,事件信号控制函数。在.NET里,封装出了ManualResetEvent、AutoResetEvent 两个类,上面四个函数就是这两个类的底层实现。
仔细看虽然有手工和自动信号量两个类,其实对应CreateEvent函数只是第二个参数去TRUE还是FALSE的区别。
那么,手动和自动的是针对什么而言的呢?实际上对信号状态重置是由谁完成来区别的。
手工信号量必须人为编程控制信号到初始状态,自动信号量由操作系统在把信号调度给等待线程中的任何一个线程(调度策略请参考操作系统核心原理方面的书)之后立即自动把信号置为初始状态。
那么,什么叫有信号呢?比如摇奖结果出来后就是有信号了,所以有人沉默、有人悲伤、有欢呼、有尖叫,在此之前,都称为无信号状态,那时大家不都在"等"吗?
看官您又要问了,信号状态重置又是什么呢?就是把信号量状态恢复到初始状态。
比如: 摇奖结果出来了,你以为地球人都知道了呀?错、错、错!如果你买了彩票突然飞去了墨西哥给人看感冒去了,墨西哥并不转播伟大的中国中央电视台,傻了吧?哪怕是你中了奖,你却高兴不起来,为啥?因为你没收到信号呀(打电话去广电总局问问不就知道了)。这就等同于尽管信号发出了,但其中的等待线程并没有收到信号,这和没发信号就是一样的效果啦。如果知道彩票摇奖结果,从网上找重播录像吧,哈哈!
好了,废话不说了,调试以下两段代码就见分晓了:
ManualResetEvent
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1usingSystem;
2usingSystem.Text;
3usingSystem.Threading;
4
5namespaceConsoleApplication1
6{
7classProgram
8{
9staticSystem.Threading.ManualResetEvente=newSystem.Threading.ManualResetEvent(false);
10
11staticstringresource="";
12
13staticvoidMain(string[]args)
14{
15resource="iamwzcheng";
16
17newThread(newThreadStart(A)).Start();
18newThread(newThreadStart(B)).Start();
19newThread(newThreadStart(C)).Start();
20
21e.Set();//发出信号,此时信号量状态为有信号态,上面三个线程得到运行
22
23Thread.CurrentThread.Join(1000);
24
25Console.WriteLine("重置信号量状态按Y,否则按N");
26
27if("N"==Console.ReadLine().ToUpper())
28{
29//此线程不会被阻塞,因为信号量有信号
30newThread(newThreadStart(D)).Start();
31}
32else
33{
34
35e.Reset();//此时信号量状态为无信号态
36
37//线程阻塞中
38newThread(newThreadStart(D)).Start();
39
40e.Set();//发出信号,此时信号量状态为有信号态,上面的线程得到运行
41}
42
43Console.ReadLine();
44}
45
46
47publicstaticvoidA()
48{
49e.WaitOne();
50Console.WriteLine("对句子进行拼写检查:{0}",resource);
51}
52
53publicstaticvoidB()
54{
55e.WaitOne();
56Console.WriteLine("对句子进行语法分析:{0}",resource);
57}
58
59publicstaticvoidC()
60{
61e.WaitOne();
62Console.WriteLine("对句子进行文本处理:{0}",resource);
63}
64
65publicstaticvoidD()
66{
67e.WaitOne();
68resource="iamXXX";
69Console.WriteLine("清空资源:{0}",resource);
70}
71}
72}
73
AutoResetEvent
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->usingSystem;
usingSystem.Text;
usingSystem.Threading;
namespaceConsoleApplication1
{
classProgram
{
staticSystem.Threading.AutoResetEvente=newSystem.Threading.AutoResetEvent(false);
staticstringresource="";
staticvoidMain(string[]args)
{
resource="iamwzcheng";
newThread(newThreadStart(A)).Start();
newThread(newThreadStart(B)).Start();
newThread(newThreadStart(C)).Start();
e.Set();
/*发出信号,此时信号量状态为有信号态,上面三个线程中随机一个得到运行。
因为三个线程等待的是自动信号量,所以在信号量发出信号后,同等机会的三个线程被CPU
挑选其中一个(这是WINDOWS操作系统调度策略,此时忽略线程优先级)唤醒。
但随后信号量立即被自动恢复到初始的无信号状态,所以其余两个线程无法运行。
*/
//如果希望其它的线程继续得到运行,可以取消线程函数中被注释掉的行//e.Set();
Console.ReadLine();
}
publicstaticvoidA()
{
e.WaitOne();
Console.WriteLine("对句子进行拼写检查:{0}",resource);
//e.Set();
}
publicstaticvoidB()
{
e.WaitOne();
Console.WriteLine("对句子进行语法分析:{0}",resource);
//e.Set();
}
publicstaticvoidC()
{
e.WaitOne();
Console.WriteLine("对句子进行文本处理:{0}",resource);
//e.Set();
}
}
}
分享到:
相关推荐
标题中的"白话经典控制理论"告诉我们,本文将采用通俗易懂的语言来介绍控制理论,避免了复杂的数学表达和难以理解的术语,使没有专业背景的读者也能理解控制理论的基本概念。 描述部分进一步强调,本文的目的是普及...
栈内存由编译器自动管理,而堆内存需要程序员手动分配和释放,这涉及到指针的使用和内存泄漏问题。了解何时使用new和delete操作符,以及智能指针(如unique_ptr、shared_ptr)的概念,是防止内存问题的重要步骤。 ...
《白话C++》教程是一本面向初学者和有一定编程基础的人士的C++学习资料。本书以通俗易懂的语言,生动有趣的例子,深入浅出地解析了C++这一强大的编程语言,使得学习者能够更轻松地掌握C++的基础与进阶知识。 C++是...
《子平真诠白话解释》对阴阳五行进行了生动的比喻和诠释,帮助读者理解它们在生活中的体现。例如,木分为阳木和阴木,甲木代表生长向上之气,而乙木则代表了承接滋养之质。这揭示了五行之间不仅存在相互促进的“相生...
白话机器学习的数学-立石贤吾-源代码.zip
白话机器学习的数学 机器学习是一种人工智能的方法论,通过让计算机自主学习数据中的规律和模式,从而完成特定的任务。机器学习有监督学习和无监督学习两种类型。在监督学习中,我们向模型提供带有标签的训练数据,...
内存管理是C++的一个重要方面,包括动态内存分配与释放(new和delete操作)、栈和堆的区别、野指针问题以及内存泄漏的预防。理解内存管理对于编写健壮的C++程序至关重要。 异常处理是C++中的错误处理机制,通过try...
在IT领域,C++是一种强大的、通用的编程语言,它以其高效性、灵活性和面向对象的特性而闻名。"白话C++编程"这个资源显然旨在以通俗易懂的方式介绍C++编程的基础知识,这对于初学者或者需要巩固基础的开发者来说是...
《白话C++》通过实例演示和生动的比喻,使这些复杂的概念变得易于理解。 总之,《白话C++》是一本精心编写的C++入门教材,它以其独特的“白话”风格,让编程学习不再枯燥乏味。无论你是编程新手还是寻求进阶的...
白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-...
《白话Windows编程》是一本面向初学者和中级程序员的指南,旨在用通俗易懂的语言讲解Windows操作系统下的程序开发技术,主要关注C++语言在Windows平台的应用。这本书深入浅出地介绍了如何使用C++进行Windows API编程...
通过以上解析,我们可以看出,《白话C++》这本书通过幽默风趣的方式,深入浅出地介绍了计算机编程的基础知识,特别是针对初学者而言,这样的教学方法非常有利于激发学习兴趣,并帮助他们更好地理解和掌握C++编程的...
《罗织经》白话全译.doc
本书对统计学原理和术语进行了简洁、清晰而准确的解释,并通过大量实例讲述统计技术的操作方法。书中涵盖了社会科学研究所使用的大部分统计原理和方法,诸如集中趋势、变异程度、正态分布、z分数、标准误等基本概念...
《白话C++》是一本非常适合初学者的C++教程,其主要目标是用通俗易懂的语言介绍C++编程的基础知识,帮助读者快速进入C++的世界。C++是一种强大而灵活的面向对象编程语言,广泛应用于系统软件、游戏开发、应用软件...
《白话C++》是一本面向C++初学者的通俗易懂的教程,它旨在以简单、生动的方式介绍C++编程语言的基础知识。C++是一种强大的、通用的、面向对象的编程语言,广泛应用于系统软件、应用软件、游戏开发、设备驱动等各个...
《白话 Windows 编程》EXE格式电子书,收藏版!!!
《2008版 白话C++》是一本针对C++初学者的教程,以易于理解的"白话"风格讲解C++编程语言的基础知识。CHM(Compiled Help Manual)格式是微软的一种帮助文件格式,它将文本、图像和其他资源压缩到一个单一的文件中,...