简体   繁体   English

信号量何时初始化为 0?

[英]When is semaphore initialized with value 0?

I am seeing a value of 0 being used in a piece of code.我看到一段代码中使用了 0 值。 We use a value of 1 for a binary semaphore and a value of N for a counting semaphore.我们将值 1 用于二进制信号量,将值 N 用于计数信号量。 Somehow the value of 0 isn't making sense to me.不知何故,0 的值对我来说没有意义。

/* Initialise the semaphore to be blocked. */

sem_t sem; 
sem_init(&sem, 0, 0);

The code is in C programming.代码在 C 编程中。 Then as usual we have sem_wait, sem_post and sem_destroy in other places within the code.然后像往常一样,我们在代码的其他地方有 sem_wait、sem_post 和 sem_destroy。

If using either 0 or 1 is fine, then why doesn't this program run -如果使用 0 或 1 都可以,那么为什么这个程序不运行 -

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

sem_t mutex;

void* thread(void* arg)
{
        //wait
        sem_wait(&mutex);
        printf("\nEntered..\n");

        //critical section
        sleep(4);

        //signal
        printf("\nJust Exiting...\n");
        sem_post(&mutex);
}


int main()
{
        sem_init(&mutex, 0, 0);
        pthread_t t1,t2;
        pthread_create(&t1,NULL,thread,NULL);
        sleep(2);
        pthread_create(&t2,NULL,thread,NULL);
        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        sem_destroy(&mutex);
        return 0;
}

The same would run if sem_init was done with sem_init(&mutex, 0, 1);如果 sem_init 使用 sem_init(&mutex, 0, 1); 完成,同样会运行。

I am seeing a value of 0 being used in a piece of code.我看到一段代码中使用了 0 值。 We use a value of 1 for a binary semaphore and a value of N for a counting semaphore.我们将值 1 用于二进制信号量,将值 N 用于计数信号量。 Somehow the value of 0 isn't making sense to me.不知何故,0 的值对我来说没有意义。

0 is a value that every semaphore can take. 0 是每个信号量都可以取的值。 Initializing a semaphore with that value is therefore perfectly reasonable.因此,使用该值初始化信号量是完全合理的。

If using either 0 or 1 is fine, then why doesn't this program run [...]如果使用 0 或 1 都可以,那么为什么这个程序不运行 [...]

Just because it is reasonable in general to initialize a semaphore to zero does not mean that doing so is appropriate for a given particular purpose.仅仅因为将信号量初始化为零通常是合理的并不意味着这样做适用于给定的特定目的。

The value of a semaphore at any given time affects its behavior.在任何给定时间,信号量的值都会影响其行为。 In particular, sem_wait() attempts to decrement a semaphore without reducing its value below zero, blocking until it can do so.特别是, sem_wait()尝试在不将其值减小到零以下的情况下减少信号量,直到它可以这样做为止。 Thus, if you initialize a semaphore with value zero then every thread that attempts to sem_wait() on it will block until some thread increases its value via sem_post() .因此,如果您初始化一个值为 0 的信号量,那么每个尝试对其sem_wait()的线程都会阻塞,直到某个线程通过sem_post()增加其值。 If you are using the semaphore as a mutex, as the example code does, then you could characterize that as the mutex being initially locked.如果您将信号量用作互斥锁,就像示例代码那样,那么您可以将其表征为互斥锁最初被锁定。

While both values are allowed and perfectly reasonable, that doesn't mean they are interchangeable.虽然这两个值都是允许的并且完全合理,但这并不意味着它们可以互换。


Imagine if you wanted Thread 2 to wait for Thread 1 to complete it's work before proceeding.想象一下,如果您希望线程 2 在继续之前等待线程 1 完成它的工作。 You could use the following:您可以使用以下内容:

main:主要的:

sem_t sem; 
sem_init(&sem, 0, 0);

Thread 1:线程 1:

do_work();
sem_post(&sem);

Thread 2:线程 2:

do_some_work();

// Wait for Thread 1 to complete before proceeding.
sem_wait(&sem);
do_other_work();

As you can see, initializing a semaphore to zero can be perfectly reasonable.如您所见,将信号量初始化为零是完全合理的。 That doesn't mean it does the same thing as initializing it to one.这并不意味着它与将其初始化为相同的事情。 Your program is buggy because your thread waits for the value of the semaphore to be raised above zero, but nothing ever does that.您的程序有问题,因为您的线程等待信号量的值高于零,但从来没有这样做过。

sem_init only sets the initial value. sem_init只设置初始值。
If during the lifetime of the semaphore its value won't exceed 1, you can call it a binary semaphore, and counting semaphore otherwise.如果在信号量的生命周期内它的值不会超过 1,你可以称它为二进制信号量,否则计数信号量。
The initial value is just the first value that the semaphore holds, not the maximum.初始值只是信号量持有的第一个值,而不是最大值。

The metaphor for a semaphore is a library with N copies of "Moby Dick".信号量的隐喻是一个拥有 N 个“Moby Dick”副本的库。 You can only check out N times and then check out waits for a check in. If you have 1 copy, it behaves like a mutex.您只能签出 N 次,然后签出等待签入。如果您有 1 个副本,它的行为就像一个互斥锁。 Starting at 0 is just starting locked, a reasonable default.从 0 开始只是开始锁定,这是一个合理的默认值。 You can tell it a larger sum before it gets tested.在它被测试之前,你可以告诉它一个更大的数目。 I would say how, but then I would have to google up the right man pages, which is what I recommend to all my students, You cannot remember it all, but you should know a little and how to find the rest.我会说怎么做,但是我必须用谷歌搜索正确的手册页,这是我向所有学生推荐的,你不能全部记住,但你应该知道一点,以及如何找到 rest。 Note that some semaphores live in memory for thread use, others in the file system for inter-process use.请注意,一些信号量存在于 memory 中以供线程使用,其他信号量位于文件系统中供进程间使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM