2012-07-30 55 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的信号量。但是,信号量不会阻止多个同时发布的帖子。如果你有信号量的虚假帖子,这将允许多个线程进入关键部分。

相关问题