zoukankan      html  css  js  c++  java
  • 多线程信号量的运用

    1、信号量的初始化sem_init()函数语法

      

    2、信号量sem_wait()操作,里面传递的参数首先-1,然后判断里面的参数-1之后是否>=0,是 则执行后面程序,否 则卡死在那里直到参数>=0 为止

        信号量sem_post()操作,里面传递的参数+1,

      

    代码分析:生产者和消费者问题

    /*producer-customer.c*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <pthread.h>
    #include <errno.h>
    #include <semaphore.h>
    #include <sys/ipc.h>
    #define MYFIFO            "myfifo"    /* 缓冲区有名管道的名字 */
    #define BUFFER_SIZE        3              /* 缓冲区的单元数 */
    #define UNIT_SIZE        5              /* 每个单元的大小 */
    #define RUN_TIME        30             /* 运行时间 */
    #define DELAY_TIME_LEVELS    5.0        /* 周期的最大值 */
    
    int fd;
    time_t end_time;
    sem_t mutex, full, avail;            /* 三个信号量 */
    
    /*生产者线程*/
    void *producer(void *arg)
    {
        int real_write;
        int delay_time = 0;
        
        while(time(NULL) < end_time)
        {
            delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX) / 2.0) + 1;
            sleep(delay_time);
            /*P操作信号量avail和mutex*/
            sem_wait(&avail);
            sem_wait(&mutex);
            printf("
    Producer: delay = %d
    ", delay_time);        
            /*生产者写入数据*/
            if ((real_write = write(fd, "hello", UNIT_SIZE)) == -1)
            {
                if(errno == EAGAIN)
                {
                    printf("The FIFO has not been read yet.Please try later
    ");
                }
            }
            else
            {
                printf("Write %d to the FIFO
    ", real_write);
            }
            
            /*V操作信号量full和mutex*/
            sem_post(&full);
            sem_post(&mutex);        
        }    
        pthread_exit(NULL);
    }
    /* 消费者线程*/
    void *customer(void *arg)
    {
        unsigned char read_buffer[UNIT_SIZE];
        int real_read;
        int delay_time;    
        
        while(time(NULL) < end_time)
        {
            delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
            sleep(delay_time);
            /*P操作信号量full和mutex*/
            sem_wait(&full);
            sem_wait(&mutex);
            memset(read_buffer, 0, UNIT_SIZE);
            printf("
    Customer: delay = %d
    ", delay_time);
    
            if ((real_read = read(fd, read_buffer, UNIT_SIZE)) == -1)
            {
                if (errno == EAGAIN)
                {
                    printf("No data yet
    ");
                }
            }
            printf("Read %s from FIFO
    ", read_buffer);
            /*V操作信号量avail和mutex*/
            sem_post(&avail);
            sem_post(&mutex);
        }
        pthread_exit(NULL);
    }
    
    int main()
    {
        pthread_t thrd_prd_id,thrd_cst_id;
        pthread_t mon_th_id;
        int ret;
        
        srand(time(NULL));
        end_time = time(NULL) + RUN_TIME;
        /*创建有名管道*/
        if((mkfifo(MYFIFO, O_CREAT|O_EXCL) < 0) && (errno != EEXIST))
        {
            printf("Cannot create fifo
    ");
            return errno;
        }            
        /*打开管道*/
        fd = open(MYFIFO, O_RDWR);
        if (fd == -1)
        {
            printf("Open fifo error
    ");
            return fd;
        }    
        /*初始化互斥信号量为1*/
        ret = sem_init(&mutex, 0, 1);
        /*初始化avail信号量为N*/
        ret += sem_init(&avail, 0, BUFFER_SIZE);
        /*初始化full信号量为0*/
        ret += sem_init(&full, 0, 0);
        if (ret != 0)
        {
            printf("Any semaphore initialization failed
    ");
            return ret;
        }
        /*创建两个线程*/
        ret = pthread_create(&thrd_prd_id, NULL, producer, NULL);
        if (ret != 0)
        {
            printf("Create producer thread error
    ");
            return ret;
        }
        ret = pthread_create(&thrd_cst_id, NULL, customer, NULL);
        if(ret != 0)
        {
            printf("Create customer thread error
    ");
            return ret;
        }
        pthread_join(thrd_prd_id, NULL);
        pthread_join(thrd_cst_id, NULL);
        close(fd);
        unlink(MYFIFO);    
        return 0;
    }

    简单点的代码,参考

    http://www.cnblogs.com/yihujiu/p/5523814.html

  • 相关阅读:
    017-新闻表分页增删改查
    016-页面生命周期
    015-用户登录注册
    014-Session服务器状态保持
    013-Cookie状态保持
    012-ViewState状态保持
    011-Server服务器对象属性
    010-判断是否回传IsPostBack属性
    Github使用教程
    获取中文时间
  • 原文地址:https://www.cnblogs.com/yihujiu/p/5597469.html
Copyright © 2011-2022 走看看