System V 信号量操作,进程间通信(…

   首先说明下System V semaphore和Posix semaphore的区别

   二者是信号量的两组程序设计接口函数。POSIX semaphore来源于POSIX技术规范的实时扩展方案(POSIX Realtime Extension),常用于线程;System V semaphore,常用于进程的同步。这两者非常相近,但它们使用的函数调用各不相同。前一种的头文件为semaphore.h,函数调用为sem_open()(Open Named Semaphore), sem_init() (Initialize Unnamed Semaphore),sem_wait(),sem_post(),sem_destory()等等。后一种头文件为<sys/sem.h>,函数调用为semctl(),semget(),semop()等函数。
   本例中的信号量使用机制来源于mm共享库,一旦锁住便不可再进入,这里使用了struct sembuf结构的二维数组,是为了同时操作信号集,如dolock()后再dolock()就会被阻塞(只能等待dounlock()解救),因为my_dolock[1].sem_op = 1使信号值为1,而在my_dolock[0].sem_op = 0中,只要当sem_op不为0就阻塞
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/sem.h>

union semun {
    int val;                    // used for SETVAL only 
    struct semid_ds *buf;       // used for IPC_STAT and IPC_SET 
    ushort *array;              // used for GETALL and SETALL 
};

#if 01
int semid;
static union  semun  my_semctlarg;
static struct sembuf my_dolock[2];
static struct sembuf my_dounlock[1];

int newSem();

void initSemBuf()
{
        my_dolock[0].sem_num = 0;
        my_dolock[0].sem_op = 0;
        my_dolock[0].sem_flg = 0;

        my_dolock[1].sem_num = 0;
        my_dolock[1].sem_op = 1;
        my_dolock[1].sem_flg = SEM_UNDO;

        my_dounlock[0].sem_num = 0;
        my_dounlock[0].sem_op = -1;
        my_dounlock[0].sem_flg = SEM_UNDO;

        semid = newSem();
}

int dolock()
{
        int ret = -1;
* __sops, which is a pointer to the struct sembuf that you filled with your semaphore commands. If you want, though, you can make an array of struct sembufs in order to do a whole bunch of semaphore operations at the same time. The way semop() knows that you're doing this is the nsop argument, which tells how many struct sembufs you're sending it. If you only have one, well, put 1 as this argument.
        while (((ret = semop(semid, my_dolock, 2)) < 0) && (errno == EINTR))
                ;

        if (ret < 0)
        {
                perror("do lock semop : ");
                abort();
        }

        return 0;
}

int dounlock()
{
        int ret = -1;

        while (((ret = semop(semid, my_dounlock, 1)) < 0) && (errno == EINTR))
                ;

        if (ret < 0)
        {
                perror("do unlock semop : ");
                abort();
        }

        return 0;
}

void showSem()
{
        fprintf(stdout, "sem val: %d\n", semctl(semid, 0, GETVAL));
}

int newSem()
{
        int semid = semget(321034, 10, IPC_CREAT | IPC_EXCL | 0666);
        if (semid < 0)
        {
                perror("semget : ");
                abort();
        }

        my_semctlarg.val = 0;
        semctl(semid, 0, SETVAL, my_semctlarg);

        return semid;
}

void freeSem()
{
        semctl(semid, 0, IPC_RMID);
}

int main()
{
        initSemBuf();

        int limit = 5;
        pid_t pid;

        if((pid = fork()) < 0){
                freeSem();
                return -1;
        }

        if(0 == pid){
                srand(time(NULL)^getpid());
                int i = 0;

                while(i++ < limit){
                        dolock();
                        int sec = rand() & 255;

                        fprintf(stdout, "child doing work...\nafter %dms finish...\n\n", sec);
                        usleep(sec);

                        dounlock();
                }

        }else{
                srand(time(NULL)^getpid());
                int i = 0;

                while(i++ < limit){
                        dolock();
                        int sec = rand() & 255;

                        fprintf(stdout, "parent doing work...\nafter %dms finish...\n\n", sec);
                        usleep(sec);

                        dounlock();
                }

        }

        usleep(1000);
        freeSem();
        return 0;
}

#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值