第三十一章 System V信号量(二)

用信号量实现进程互斥示例

#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>

union semun {
    int              val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                (Linux-specific) */
};

#define ERR_EXIT(m)         \
    do                      \
    {                       \
        perror(m);          \
        exit(EXIT_FAILURE); \
    } while (0)

int sem_create(key_t key)
{
    int semid;
    semid = semget(key, 1, IPC_CREAT|IPC_EXCL| 0666);
    if(semid == -1)
        ERR_EXIT("semget");
    
    return semid;
}

int sem_open(key_t key)
{
    int semid;
    semid = semget(key, 0, 0);
    if(semid == -1)
        ERR_EXIT("semget");

    return semid;
}

int sem_setval(int semid, int val)
{
    union semun su;
    su.val = val;
    int ret;
    ret = semctl(semid, 0, SETVAL, su);
    if(ret == -1)
        ERR_EXIT("semctl");

    return 0;
}

int sem_del(int semid)
{
    int ret;
    ret = semctl(semid, 0, IPC_RMID, 0);
    if(ret == -1)
        ERR_EXIT("semctl");

    return 0;
}

int sem_getval(int semid, int val)
{
    int ret;
    ret = semctl(semid, 0, GETVAL, 0);
    if(ret == -1)
        ERR_EXIT("semctl getval");

    return ret;
}

int sem_p(int semid)
{
    struct sembuf sops = {0, -1, 0};
    int ret;
    ret = semop(semid, &sops, 1);
    if(ret == -1)
        ERR_EXIT("semop");

    return 0;
}

int sem_v(int semid)
{
    struct sembuf sops = {0, 1, 0};
    int ret;
    ret = semop(semid, &sops, 1);
    if(ret == -1)
        ERR_EXIT("semop");

    return 0;
}

int semid;
void print(char ch)
{
    int pause_time;
    srand(getpid());
    int i;
    for(i=0; i < 10; ++i)
    {
        sem_p(semid);

        printf("%c", ch);
        fflush(stdout);
        pause_time = rand() % 3;
        sleep(pause_time);

        printf("%c", ch);
        //fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃[非标准]
        //fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上
        fflush(stdout);

        sem_v(semid);

        pause_time = rand() % 2;
        sleep(pause_time);
    }

}


int main(int argc, char* argv[])
{

    semid = sem_create(IPC_PRIVATE);

    sem_setval(semid, 0);
    
    pid_t pid;
    pid = fork();
    if(pid == -1)
        ERR_EXIT("fork");
    
    if(pid > 0)
    {
        sem_setval(semid,1);
        print('O');

        wait(NULL);
        sem_del(semid);
    }
    else
    {
        print('X');
    }
    

    return 0;
}

结果

./semget 
OOXXOOXXOOXXXXOOXXOOXXOOXXOOXXOOXXOOXXOO

./semget 
OOXXOOXXOOXXOOXXOOXXOOXXOOXXOOXXOOXXOOXX
posted @ 2019-09-25 16:16  sfdevs  阅读(149)  评论(0编辑  收藏  举报