对于所有人来说,这可能是一个非编程问题,我确实读过一些关于线程同步对象(如event )的文章,以及如何将其设置为信号状态或非信号状态。然而,我无法理解这些术语,发出信号,没有信号,,.Each,one以不同的方式表达,我有点困惑。
用一个例子简单地解释一下这个概念将是非常有帮助的。
发布于 2013-07-12 11:19:25
好吧,你的三个引号不是不兼容的。但是,让我们深入讨论一下实现:
每个可等待对象都附加了一个布尔值,名为信号状态,用于等待该对象;如果该对象被发送信号,则等待函数将而不是等待它;如果该对象没有信号,则等待函数将对其进行等待。
现在,这如何应用于特定类型的对象?这取决于对象的性质,特别是与等待对象相关的语义。实际上,信号状态是用等待条件来定义的。例如(有关详细信息,请参阅文档):
如果一个互斥在拥有时发出信号,你可能会更喜欢,但实际上它是在不拥有的时候。这对于让等待函数做正确的事情是必要的。
那这些事件呢?嗯,它们是一些简单的对象,您可以随意发送信号和去信号,因此信号状态没有额外的含义:
事件也有一些特殊的SignalPulse和AutoReset (而且IME几乎不可能正确使用)。
现在,让我们看看你的引语:
发出信号的状态指示资源可供进程或线程使用。未发出信号的状态指示正在使用的资源。
实际上,这是一种解释。通常有一个资源你在试图仲裁,通常你等待如果和唯一-如果该资源正在使用,所以它是在资源使用和等待资源之间的等价。但这不是技术要求,只是一个常用的用例。
处于信号状态的对象不会导致等待对象的线程阻塞,而处于信号状态的对象将导致等待该对象的任何线程阻塞,直到该对象再次发出信号为止。
正确,切中要害!
事件处于信号状态,意味着它有能力释放等待此事件被发送信号的线程。事件处于无信号状态,意味着它不会释放等待此特定事件的任何线程。
我觉得这个措辞有点混乱..。但它并没有比前一个增加任何东西。
发布于 2013-07-12 13:24:29
简单的想法:“信号”=“绿灯”

向发出信号:如果您正在开车,看到了绿灯,您就不会停下来(这是查看事件的线程,发现是发出了信号,并且没有阻塞地继续进行)。

Non-Signalled:,如果你看到红灯,你就停下来,等它变绿,然后继续(安全地知道,其他线程现在都没有信号了,因此正在等待或将在their...red灯前等待!)
发布于 2013-07-12 11:23:17
事实上,所有这些解释都是一致的。
对事件的最简化(因此不是100%准确)解释是将事件看作是操作系统提供的一种标志服务。信号事件可以看作是一个集合标志,而一个没有信号的事件则可以看作是一个未设置的标志。
为了实现基于标志的生产者/使用者线程系统,您通常执行如下操作(为了简单起见,我忽略了进一步的同步机制):
static volatile int flag = 0;
static volatile char data = 'A';
// Some code to initialize the threads
void producer()
{
while (1)
{
Sleep(1000);
data++;
flag = 1;
}
}
void consumer()
{
while (1)
{
/* Busy wait for the occurence of more data */
while (!flag)
{
// wait for next data
}
flag = 0;
// process data
}
}不幸的是,这将导致在繁忙的等待循环中浪费处理器周期,或者由于引入Sleep调用以降低CPU消耗而导致不必要的执行延迟。两者都是多余的。
为了避免任务同步出现这样的问题,操作系统提供了不同的类似标记的机制(例如Windows中的事件)。对于事件,通过OS调用SetEvent/ResetEvent来设置和重置标志。若要检查标志,可以使用WaitForSingleObject。这个调用可以让任务进入休眠状态,直到事件得到信号为止,这在CPU消耗方面是最优的。
这会将上面的示例转换为如下所示:
static volatile char data = 'A';
static HANDLE newDataEvent = INVALID_HANDLE_VALUE;
// Some code to initialize the threads and the newDataEvent handle
void producer()
{
while (1)
{
Sleep(1000);
data++;
SetEvent(newDataEvent);
}
}
void consumer()
{
while (1)
{
if (WaitForSingleObject(newDataEvent, INFINITE) == WAIT_OBJECT_0)
{
ResetEvent(newDataEvent);
// process data
}
}
}https://stackoverflow.com/questions/17613342
复制相似问题