如何正确的理解使用posix1提供的信号量

    我们在使用unix/linux系统中,往往会在使用信号量时,出现比较茫然的状态。我们倒地时使用System V系统的信号量还是posix1建议实现的信号量呢?因为posix1建议实现的信号量,并非在所有unix/linux平台得到实现,所以即使使用,对于移植性来说,也未必可以得到肯定的答案。但是无论如何,个人认为我们还是最好使用posix1提供的信号量,有部分的原因请参考 如何使用System V的信号量中所述。下面的主要内容,我也将重点讨论posix1所提供的信号量。
   对于posix1提供的信号量,它提供了两种形式。
一是命名的信号量,它可以被多个进程所共享,并且时kernel persistent。也就是说,如果没有使用sem_unlink函数,那么它一直占用系统资源,直到系统reboot为止。它比System V系统提供的信号量最大的优点是,对信号量的创建和初始化操作是原子的,避免了在这里的竞争关系。我们可以通过sem_open, sem_wait, sem_post,sem_unlink来创建、等待、删除等操作。sem_unlink不是立刻把对应的信号量删除,而是在open计数达到0的时候才真正的从系统中将它删除,否则一直滞留在系统中:)。sem_open对于多个相关或者无关的进程而言是安全的,我们可以这么使用:
1)在相关进程中
sem_t *pSem = sem_open( ... );
if ( fork() == 0 )  //子进程
{
    sem_wait( pSem ); //完全有效,工作正常
     exit( 0 );
}
父进程
 2)在多个不相关进程中
进程1
sem_t *pSem = open ( SEM_NAME, O_CREAT | O_EXCL, .. );
进程2
sem_t *pSem = open( SEM_NAME, ...)
进程1和2都能够容易获取相关信号量,使用共享资源。

二是匿名信号量,也就是内存信号量。它的获取是通过 int sem_init(sem_t *sem, int pshared, unsigned int value);函数。pShared指明是否它可用于多进程,1可以,0不可以。它的优点显而易见,很方便的创建和使用并且在所有相关进程消亡的时候自动消亡,但是缺点也非常的明显。如果在被使用多进程环境中,它的副本是不能被使用的。请看下面:
sem_int( &sem, 1, 1 );
if ( fork() == 0 )//子进程
{
   sem_wait( &sem ); //错误,posix1标准说,对它的副本的使用是不可预知的。
   exit( 0 )
}
那么怎么使用了,很简单,就是要将它放入到共享内存中去,这样,子父进程都能够正确的使用它了。

posix1标准也提供了互斥,那么如何选定在程序中使用互斥还是信号量呢?请参考 浅析信号量(Semaphore)和互斥(Mutex)。简单的说,如果在多进程中,最好使用命名信号量,否则使用互斥。

你可能感兴趣的:(工作,Semaphore,System,平台)