如何開啟現有的命名信號量?

如何開啟現有的命名信號量?

顯然,當打開現有信號量時,O_CREATO_EXCL不是必需的。

O_CREAT建立新信號量時需要。

O_EXCL僅當與 進行 OR 運算時才有意義O_CREAT,指定如果具有給定名稱的信號量已存在,則傳回錯誤。

sem_open 的 Linux 手冊頁

可以透過包含 <fcntl.h> 來取得標誌值的定義

但我沒有找到任何標誌fcntl.h這告訴我如何開啟現有的信號量。

答案1

考慮以下範例:

#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    const char* const sem_name = "lock.sem";

    if (argc == 1) {
        sem_t* const sem = sem_open(sem_name, O_CREAT, 0644, 0);

        if (sem == NULL) {
            perror("sem_open");
            return 1;
        }

        sem_wait(sem); // Will block
        sem_close(sem);

        sem_unlink(sem_name);
    } else {
        sem_t* const sem = sem_open(sem_name, 0);

        if (sem == NULL) {
            perror("sem_open");
            return 1;
        }

        sem_post(sem); // Will unblock the other process
        sem_close(sem);
    }

    return 0;
}

我使用參數計數來控製程式的行為。

如果我不提供任何參數(即,何時argc == 1),則程式將開啟信號量,如果信號量尚不存在則創建它;它將信號量的值初始化為0。然後它對物件執行 asem_wait()操作sem。由於信號量被初始化為0,這會導致進程阻塞。

現在,如果我運行同一程式的第二個實例,但這次使用任何非零數量的參數(即,when argc != 1),則程式將開啟信號量,但如果信號量尚不存在,則不會建立它。請注意,我傳遞0了參數oflag(即,我沒有傳遞任何標誌)。然後程式執行 a 操作sem_post(),將信號量從0增加到1。這將解除第一個進程的阻塞。兩個進程都將關閉對信號量的引用並終止。

如果我正確理解你的問題,第二種情況就是你要尋找的。

如果我嘗試先運行第二種情況(即,當第一種情況沒有正在運行的實例時),那麼我會得到:

$ ./a.out foo
sem_open: No such file or directory

這是從呼叫來的,perror()因為具有給定名稱的信號量不存在。

相關內容