• 多线程信号量的运用


    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

  • 相关阅读:
    master线程的主循环,后台循环,刷新循环,暂停循环
    InnoDB的后台线程(IO线程,master线程,锁监控线程,错误监控线程)和内存(缓冲池,重做日志缓冲池,额外内存池)
    MySQL的连接方式
    编写高质量的 Java 代码
    TProfiler
    Copy-On-Write容器
    G1 垃圾收集器
    JAVA 虚拟机钩子
    Future和Promise
    算法笔记_134:字符串编辑距离(Java)
  • 原文地址:https://www.cnblogs.com/yihujiu/p/5597469.html
Copyright © 2020-2023  润新知