zoukankan      html  css  js  c++  java
  • 信号量

    /*
     * semgTest.cpp
     *
     *  Created on: Jun 27, 2013
     *      Author: zsf
     */
    #include "semgTest.h"
    
    //联合类型semun定义
    union semun {
            int val;
            struct semid_ds *buf;
            unsigned short *array;
    };
    
    //函数声明
    //函数:设置信号量的值
    static int set_semvalue(void);
    //函数:删除信号量
    static void del_semvalue(void);
    //函数:信号量P操作
    static int semaphore_p(void);
    //函数:信号量V操作
    static int semaphore_v(void);
    
    static int sem_id;//信号量ID
    
    
    int main(int argc, char *argv[]) {
        int i;
        int pause_time;
        char op_char = 'O';
    
        srand((unsigned int) getpid());
    
    
        //创建一个新的信号量或者是取得一个已有信号量的键
        sem_id = semget((key_t) 1234, 1, 0666 | IPC_CREAT);
    
    
        //如果参数数量大于1,则这个程序负责创建信号和删除信号量
        if (argc > 1) {
            if (!set_semvalue()) {
                fprintf(stderr, "failed to initialize semaphore
    ");
                exit(EXIT_FAILURE);
            }
    
            op_char = 'X';//对进程进行标记
            sleep(5);
        }
    
        //循环:访问临界区
        for (i = 0; i < 10; ++i) {
            //P操作,尝试进入缓冲区
            if (!semaphore_p())
                exit(EXIT_FAILURE);
            printf("%c", op_char);
            fflush(stdout);//刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上
    
            pause_time = rand() % 3;
            sleep(pause_time);
    
            printf("%c", op_char);
            fflush(stdout);
    
    
            //V操作,尝试离开缓冲区
            if (!semaphore_v())
                exit(EXIT_FAILURE);
            pause_time = rand() % 2;
            sleep(pause_time);
        }
    
        printf("
     %d - finished 
    ", getpid());
    
        if (argc > 1) {
            sleep(10);
            del_semvalue();//删除信号量
        }
    }
    
    //函数:设置信号量的值
    static int set_semvalue(void) {
        union semun sem_union;
        sem_union.val = 1;
    
        if (semctl(sem_id, 0, SETVAL, sem_union))
            return 0;
    
        return 1;
    }
    
    //函数:删除信号量
    static void del_semvalue(void) {
        union semun sem_union;
    
        if (semctl(sem_id, 0, IPC_RMID, sem_union))
            fprintf(stderr, "Failed to delete semaphore
    ");
    }
    
    //函数:信号量P操作:对信号量进行减一操作
    static int semaphore_p(void) {
        struct sembuf sem_b;
    
        sem_b.sem_num = 0;//信号量编号
        sem_b.sem_op = -1;//P操作
        sem_b.sem_flg = SEM_UNDO;
    
        if (semop(sem_id, &sem_b, 1) == -1) {
            fprintf(stderr, "semaphore_p failed
    ");
            return 0;
        }
    
        return 1;
    }
    
    //函数:信号量V操作:对信号量进行加一操作
    static int semaphore_v(void) {
        struct sembuf sem_b;
    
        sem_b.sem_num = 0;//信号量编号
        sem_b.sem_op = 1;//V操作
        sem_b.sem_flg = SEM_UNDO;
    
        if (semop(sem_id, &sem_b, 1) == -1) {
            fprintf(stderr, "semaphore_v failed
    ");
            return 0;
        }
    
        return 1;
    
    }
     1 /*
     2  * semtest.cpp
     3  *
     4  *  Created on: Jun 27, 2013
     5  *      Author: zsf
     6  */
     7 
     8 #include <stdio.h>
     9 #include <stdlib.h>
    10 #include <sys/types.h>
    11 #include <sys/ipc.h>
    12 #include <sys/sem.h>
    13 #include <sys/stat.h>
    14 #include <fcntl.h>
    15 #include <unistd.h>
    16 #include <string.h>
    17 #include <strings.h>
    18 
    19 union semun {
    20         int val;
    21         struct semid_ds *buf;
    22         unsigned short int *array;
    23         struct seminfo *__buf;
    24 };
    25 
    26 int main(void) {
    27     char* buf_child[] = { "this""is""the""child""process" };
    28     char* buf_father[] = { "father""say""hello""to""child" };
    29     int i = 0, semid, fd;
    30     pid_t pid;
    31     struct sembuf sb; //信号量操作
    32     union semun sem;
    33     semid = semget(100020666 | IPC_CREAT); //申请信号量组,包含2个信号量
    34 
    35     sem.val = 0;
    36     semctl(semid, 0, SETVAL, sem); //初始化0号信号量为0
    37     sem.val = 1;
    38     semctl(semid, 1, SETVAL, sem); //初始化1号信号量为1
    39 
    40     fd = open("./tmp", O_CREAT | O_TRUNC | O_WRONLY, 0666);
    41 
    42     pid = fork();
    43     switch (pid) {
    44         case -1:
    45             perror("fork fail");
    46             break;
    47         case 0/* child consume */
    48             srand((unsigned int) getpid());
    49             while (i < 5) {
    50                 sb.sem_num = 1//将1号信号量
    51                 sb.sem_op = -1//减1
    52                 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
    53                 semop(semid, &sb, 1);
    54 
    55                 write(fd, buf_child[i], strlen(buf_child[i]));
    56                 sleep(rand());
    57                 write(fd, &" "1);
    58                 i++;
    59 
    60                 sb.sem_num = 0//将0号信号量
    61                 sb.sem_op = 1//加1
    62                 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
    63                 semop(semid, &sb, 1); //操作信号量
    64             }
    65             break;
    66         default:/* parent production  */
    67             srand((unsigned int) getpid());
    68             while (i < 5) {
    69                 sb.sem_num = 0//将0号信号量
    70                 sb.sem_op = -1//减1
    71                 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
    72                 semop(semid, &sb, 1); //操作信号量
    73 
    74                 write(fd, buf_father[i], strlen(buf_father[i]));
    75                 sleep(rand());
    76                 write(fd, &" "1);
    77                 i++;
    78 
    79                 sb.sem_num = 1;
    80                 sb.sem_op = 1;
    81                 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
    82                 semop(semid, &sb, 1);
    83             }
    84             break;
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    python 基础第二篇
    python 基础第五篇
    python 基础第四篇
    购物小编程(完整编码)
    计算机 python概论
    str 相关操作
    python 基础第三篇
    Nginx 配置多站点vhost
    h5页面宽度设置7.5rem
    js 倒计时,转义
  • 原文地址:https://www.cnblogs.com/zhangsf/p/3158737.html
Copyright © 2011-2022 走看看