linux 命名信号量实现进程间的互斥与同步

转:http://www.oschina.net/code/snippet_237505_8646#13755

     howaylee 发布于 2012年02月12日 20时


/* 
   命名信号量不带内存共享,编译时要带库文件-lpthread或-lrt 
   int sem_wait(sem_t *sem); //P操作,若是信号量大于零则减一,否则阻塞在该函数位置等待. 
   int sem_post(sem_t *sem); //V操作,信号量加一 
   sem_t *sem_open(const char *name, int oflag);//打开信号量,flag参数与打开普通文件的标记一样 
   sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value); 
 //创建并打开信号量,value参数指的是信号量的初始值 
int sem_unlink(const char *name);//删除系统创建的信号量 
int sem_close(sem_t *sem);//关闭彻底销毁信号量 
 */ 


sem_dan_syn.c

#include <stdio.h>
#include <errno.h>
#include <semaphore.h>
#include <fcntl.h>
 
/*
    命名信号量不带内存共享,编译时要带库文件-lpthread或-lrt
    int sem_wait(sem_t *sem); //P操作,若是信号量大于零则减一,否则阻塞在该函数位置等待.
    int sem_post(sem_t *sem); //V操作,信号量加一
    sem_t *sem_open(const char *name, int oflag);//打开信号量,flag参数与打开普通文件的标记一样
    sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value);
//创建并打开信号量,value参数指的是信号量的初始值
int sem_unlink(const char *name);//删除系统创建的信号量
int sem_close(sem_t *sem);//关闭彻底销毁信号量
  */
 
/*进程排斥*/
 
#define SEM_NAME "mysem"
#define OPEN_FLAG O_RDWR|O_CREAT
#define OPEN_MODE 00777
#define INIT_V    0
static sem_t *sem = NULL;
 
static void mysem( char *str)
{
     int i = 0;
     while ( '\0' != str[i])
     {
         printf ( "%c\n" , str[i++]);
         sleep(1);
     }
}
 
 
/*单次同步, 把信号量先初始化为0*/
 
int main( void )
{
 
     pid_t pid = -1;
     int ret = -1;
     int status = -1;
 
     //创建一个命名信号量
     sem = sem_open(SEM_NAME, OPEN_FLAG, OPEN_MODE, INIT_V);
 
     //创建子进程
     pid = fork();
     if (-1 == (ret = pid))
     {
         perror ( "fork failed: " );
         goto _OUT;
     }
 
     if (0 == pid)
     {
         mysem( "abcd" );
         //V操作
         sem_post(sem);
     }
 
     if (0 < pid)
     {
         //P操作
         sem_wait(sem);
         mysem( "1234" );
         //等待子进程结束
         wait(&status);
         //删掉在系统创建的信号量
         sem_unlink(SEM_NAME);
         //彻底销毁打开的信号量
         sem_close(sem);
     }
 
_OUT:
     return ret;
}





 sem_diedai_syn.c

#include <stdio.h>
#include <errno.h>
#include <semaphore.h>
#include <fcntl.h>
#include <signal.h>
 
/*
    命名信号量不带内存共享,编译时要带库文件-lpthread或-lrt
    int sem_wait(sem_t *sem); //P操作,若是信号量大于零则减一,否则阻塞在该函数位置等待.
    int sem_post(sem_t *sem); //V操作,信号量加一
    sem_t *sem_open(const char *name, int oflag);//打开信号量,flag参数与打开普通文件的标记一样
    sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value);
//创建并打开信号量,value参数指的是信号量的初始值
int sem_unlink(const char *name);//删除系统创建的信号量
int sem_close(sem_t *sem);//关闭彻底销毁信号量
  */
 
#define SEM_NAME1 "mysem1"
#define SEM_NAME2 "mysem2"
#define OPEN_FLAG O_RDWR|O_CREAT
#define OPEN_MODE 00777
 
static sem_t *sem1 = NULL;
static sem_t *sem2 = NULL;
 
//临界区
static void mysem( char *str)
{
     int i = 0;
     while ( '\0' != str[i])
     {
         printf ( "%c\n" , str[i++]);
         sleep(1);
     }
}
//信号捕捉处理
static void myhandler( void )
{
         //删掉在系统创建的信号量
         sem_unlink(SEM_NAME1);
         sem_unlink(SEM_NAME2);
         //彻底销毁打开的信号量
         sem_close(sem1);   
         sem_close(sem2);   
}
 
 
/*迭代同步,两个信号量,开始时一个为1,一个为0, 一个进程执行完换另一个进程运行*/
 
int main( void )
{
 
     pid_t pid = -1;
     int ret = -1;
     int status = -1;
 
     //安装捕捉信号
     signal (SIGINT,( void *)myhandler );
 
     //创建一个命名信号量
     sem1 = sem_open(SEM_NAME1, OPEN_FLAG, OPEN_MODE, 1);   
     sem2 = sem_open(SEM_NAME2, OPEN_FLAG, OPEN_MODE, 0);   
 
     //创建子进程
     pid = fork();
     if (-1 == (ret = pid))
     {
         perror ( "fork failed: " );
         goto _OUT;
     }
 
     if (0 == pid)
     {
         while (1)
         {
         //P操作
         sem_wait(sem1);
         mysem( "abcd" );
         //V操作
         sem_post(sem2);
         }
     }
 
     if (0 < pid)
     {
         while (1)
         {
         //P操作
         sem_wait(sem2);
         mysem( "1234" );
         //V操作
         sem_post(sem1);
         }
         //等待子进程结束
         wait(&status);
     }
 
_OUT:
     return ret;
}



sem_paichi.c

#include <stdio.h>
#include <errno.h>
#include <semaphore.h>
#include <fcntl.h>
 
/*
    命名信号量不带内存共享,编译时要带库文件-lpthread或-lrt
    int sem_wait(sem_t *sem); //P操作,若是信号量大于零则减一,否则阻塞在该函数位置等待.
    int sem_post(sem_t *sem); //V操作,信号量加一
    sem_t *sem_open(const char *name, int oflag);//打开信号量,flag参数与打开普通文件的标记一样
    sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value);
     //创建并打开信号量,value参数指的是信号量的初始值
int sem_unlink(const char *name);//删除系统创建的信号量
int sem_close(sem_t *sem);//关闭彻底销毁信号量
  */
 
 
#define SEM_NAME "mysem"
#define OPEN_FLAG O_RDWR|O_CREAT
#define OPEN_MODE 00777
#define INIT_V    1
static sem_t *sem = NULL;
 
static void mysem( char *str)
{
     int i = 0;
     //P操作
     sem_wait(sem);
     while ( '\0' != str[i])
     {
         printf ( "%c\n" , str[i++]);
         sleep(1);
     }
     //V操作
     sem_post(sem);
}
 
 
/*进程排斥,在临界区设置PV操作*/
 
int main( void )
{
 
     pid_t pid = -1;
     int ret = -1;
     int status = -1;
 
     //创建一个命名信号量
     sem = sem_open(SEM_NAME, OPEN_FLAG, OPEN_MODE, INIT_V);
 
     //创建子进程
     pid = fork();
     if (-1 == (ret = pid))
     {
         perror ( "fork failed: " );
         goto _OUT;
     }
     
     if (0 == pid)
     {
         mysem( "abcd" );
     }
     
     if (0 < pid)
     {
         mysem( "1234" );
         //等待子进程结束
         wait(&status);
         //删掉在系统创建的信号量
         sem_unlink(SEM_NAME);
         //彻底销毁打开的信号量
         sem_close(sem);
     }
 
_OUT:
     return ret;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值