2012-07-30 52 views
1

我在代碼中遇到信號量問題。是否有可能爲所有進程創建全局信號量?

這是我建立一個結構:

struct PipeShm 
{ 
     // doesn't matter 
     sem_t *mutex; 
     int init; 
     // more fields 
}; 

在這裏,我初始化結構:

struct PipeShm myPipe ; 
myPipe.mutex = NULL; 
myPipe.init = 0; 

而且我用一個初始化方法:

int initMethod() 
{ 
    if (!myPipe.init) 
    { 
     myPipe.mutex = mmap (NULL, sizeof *myPipe.mutex, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
     if (!sem_init (myPipe.mutex, 1, 0)) 
     { 
      myPipe.init = TRUE; 
     } 
     else 
      perror ("initMethod"); 
    } 
    return 1; 
} 

這是一個簡單的主要使用以上:

int main() 

{ 
    int spd, pid, rb; 
    char buff[4096]; 


    shm_pipe_init(); 
    fork(); 

     // more code goes here 

     return 0; 
} 

在行fork();(請糾正我,如果我錯了)2進程將 有兩個不同的信號量,對不對?

如果是這樣,我想做一個全球信號量。那可能嗎?

由於我的代碼中存在同步問題,我懷疑主要原因是每個創建的進程都有一個雙重信號量 。

+0

是的,它被稱爲鎖文件 – tbert 2012-07-30 18:32:28

+0

@tbert:我不能使用(文件,我的意思是) – ron 2012-07-30 18:34:01

+0

那麼你可能想看看你的手冊頁,因爲「man sem_init」導致我「sem_open」,其中說:「sem_open()函數建立一個命名信號量和進程之間的連接」,這看起來就像你在這裏試圖做的。 – tbert 2012-07-30 18:37:34

回答

1

您的初始化信號量的代碼看起來是正確的,所以您將不得不在別處尋找同步問題。下面是一個測試程序,它說明了你的代碼的工作行爲:

void do_child() { 
    fprintf(stderr, "[%u] child: waiting...\n", (unsigned)time(0)); 
    sem_wait(myPipe.mutex); 
    fprintf(stderr, "[%u] child: sleeping 1...\n", (unsigned)time(0)); 
    sleep(1); 
    fprintf(stderr, "[%u] child: posting...\n", (unsigned)time(0)); 
    sem_post(myPipe.mutex); 
    fprintf(stderr, "[%u] child: done...\n", (unsigned)time(0)); 
} 

void do_parent (pid_t p) { 
    fprintf(stderr, "[%u] parent: sleeping 5...\n", (unsigned)time(0)); 
    sleep(5); 
    fprintf(stderr, "[%u] parent: posting...\n", (unsigned)time(0)); 
    sem_post(myPipe.mutex); 
    fprintf(stderr, "[%u] parent: waiting...\n", (unsigned)time(0)); 
    sem_wait(myPipe.mutex); 
    fprintf(stderr, "[%u] parent: waitpid...\n", (unsigned)time(0)); 
    waitpid(p, 0, 0); 
    fprintf(stderr, "[%u] parent: done...\n", (unsigned)time(0)); 
} 

int main() { 
    pid_t p; 
    myPipe.mutex = NULL; 
    myPipe.init = 0; 
    initMethod(); 
    switch ((p = fork())) { 
    case 0: do_child(); break; 
    case -1: perror("fork"); break; 
    default: do_parent(p); break; 
    } 
    return 0; 
} 

我想你已經知道了,但爲了以防萬一,一個信號是不是一個真正的互斥。您可以將互斥量視爲已初始化爲後值1的信號量。但是,信號量不會阻止多個同時發佈的帖子。如果你有信號量的虛假帖子,這將允許多個線程進入關鍵部分。

相關問題