APUE Learning Example Source Code
guowenxue
2020-04-30 b0053f87034ff358b7ccadc7f2d9643e9a7767e7
ch6_ipc/semaphore.c
@@ -9,7 +9,7 @@
#include <sys/sem.h>
#define FTOK_PATH            "/dev/zero"
#define FTOK_PROJID          0x666
#define FTOK_PROJID          0x22
union semun 
{
@@ -18,18 +18,52 @@
    unsigned short *arry;
};
int semaphore_init(void);
int semaphore_p(int semid);
int semaphore_v(int semid);
void semaphore_term(int semid);
int main(int argc, char **argv)
{
    int            semid;
    pid_t          pid;
    int            i;
    if( (semid=init_set(1)) < 0)
    if( (semid=semaphore_init()) < 0)
    {
   printf("semaphore initial failure: %s\n", strerror(errno));
        return -1;
    }
    if( (pid=fork()) < 0)
    {
        printf("fork() failure: %s\n", strerror(errno));
        return -2;
    }
    else if( 0 == pid)  /* child process */
    {
        printf("Child process start running and do something now...\n");
        sleep(3);
        printf("Child process do something over...\n");
        semaphore_v(semid);
        sleep(1);
        printf("Child process exit now\n");
        exit(0);
    }
    printf("Parent process P operator wait child process over\n");
    semaphore_p(semid);
    printf("Parent start do something now...\n");
    sleep(2);
    printf("Perent process destroy semaphore and exit\n");
    semaphore_term(semid);
    return 0;
}
int init_set(int nums)
int semaphore_init(void)
{
    key_t          key;
    int            semid;
@@ -41,20 +75,72 @@
   return -1;
    } 
    
    semid = semget(key, nums, IPC_CREAT|IPC_EXCL|0644);
    semid = semget(key, 1, IPC_CREAT|0644);
    if( semid < 0)
    {
   printf("semget() get semid failure: %s\n", strerror(errno)); 
   return -2;
    }
    sem_union.val = 1;
    sem_union.val = 0;
    if( semctl(semid, 0, SETVAL, sem_union)<0 )
    {
   printf("semctl() set initial value failure: %s\n", strerror(errno)); 
   return -3;
    }
    printf("Semaphore get key_t[0x%x] and semid[%d]\n", key, semid);
    return semid;
}
void semaphore_term(int semid)
{
    union semun    sem_union;
    if( semctl(semid, 0, IPC_RMID, sem_union)<0 )
    {
   printf("semctl() delete semaphore ID failure: %s\n", strerror(errno));
    }
    return ;
}
int semaphore_p(int semid)
{
    struct sembuf _sembuf;
    _sembuf.sem_num = 0;
    _sembuf.sem_op = -1;
    _sembuf.sem_flg = SEM_UNDO; //  IPC_NOWAIT  SEM_UNDO
    if( semop(semid, &_sembuf, 1) < 0 )
    {
        printf("semop P operator failure: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}
int semaphore_v(int semid)
{
    struct sembuf _sembuf;
    _sembuf.sem_num = 0;
    _sembuf.sem_op = 1;
    _sembuf.sem_flg = SEM_UNDO; //  IPC_NOWAIT  SEM_UNDO
    if( semop(semid, &_sembuf, 1) < 0 )
    {
        printf("semop V operator failure: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}