多线程信号量的运用

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("\nProducer: delay = %d\n", 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\n");
            }
        }
        else
        {
            printf("Write %d to the FIFO\n", 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("\nCustomer: delay = %d\n", delay_time);

        if ((real_read = read(fd, read_buffer, UNIT_SIZE)) == -1)
        {
            if (errno == EAGAIN)
            {
                printf("No data yet\n");
            }
        }
        printf("Read %s from FIFO\n", 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\n");
        return errno;
    }            
    /*打开管道*/
    fd = open(MYFIFO, O_RDWR);
    if (fd == -1)
    {
        printf("Open fifo error\n");
        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\n");
        return ret;
    }
    /*创建两个线程*/
    ret = pthread_create(&thrd_prd_id, NULL, producer, NULL);
    if (ret != 0)
    {
        printf("Create producer thread error\n");
        return ret;
    }
    ret = pthread_create(&thrd_cst_id, NULL, customer, NULL);
    if(ret != 0)
    {
        printf("Create customer thread error\n");
        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

posted @ 2016-06-19 09:36  我有一壶酒  阅读(969)  评论(0编辑  收藏  举报