`
shake863
  • 浏览: 634123 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

linux下编程学习----- 线程同步之无名信号量

阅读更多

 

这是一个书上的例子,逻辑是:一个线程生产一组数字1、2、3..... 等等,放入一个循环队列中。另一个线程去处理这些数字,达到的效果是把这些数字求和。还是看看代码吧。 


#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <semaphore.h>
#define BUFSIZE 4
#define NUMBER 8

int sum_of_number=0;
/* 可读 和 可写资源数*/
sem_t write_res_number;
sem_t read_res_number;

/* 循环队列 */
struct recycle_buffer{
    int buffer[BUFSIZE];
    int head,tail;
}re_buf;

/* 用于实现临界区的互斥锁,我们对其初始化*/
pthread_mutex_t buffer_mutex=PTHREAD_MUTEX_INITIALIZER;

static void *producer(void * arg)
{
    int i;
    for(i=0;i<=NUMBER;i++)
    {
        /* 减少可写的资源数 */
        sem_wait(&write_res_number);
        /* 进入互斥区 */
        pthread_mutex_lock(&buffer_mutex);
        /*将数据复制到缓冲区的尾部*/
        re_buf.buffer[re_buf.tail]=i;
        re_buf.tail=(re_buf.tail+1)%BUFSIZE;
        printf("procuder %d write %d.\n",pthread_self(),i);
        /*离开互斥区*/
        pthread_mutex_unlock(&buffer_mutex);
        /*增加可读资源数*/
        sem_post(&read_res_number);
    }
   
    /* 线程终止,如果有线程等待它们结束,则把NULL作为等待其结果的返回值*/
    return NULL;
}

static void * consumer(void * arg)
{
    int i,num;
   
    for(i=0;i<=NUMBER;i++)
    {
        /* 减少可读资源数 */
        sem_wait(&read_res_number);
        /* 进入互斥区*/
        pthread_mutex_lock(&buffer_mutex);
        /* 从缓冲区的头部获取数据*/
        num = re_buf.buffer[re_buf.head];
        re_buf.head = (re_buf.head+1)%BUFSIZE;
        printf("consumer %d read %d.\n",pthread_self(),num);
        /* 离开互斥区*/
        pthread_mutex_unlock(&buffer_mutex);
        sum_of_number+=num;
        /* 增加客写资源数*/
        sem_post(&write_res_number);
    }       
    /* 线程终止,如果有线程等待它们结束,则把NULL作为等待其结果的返回值*/
    return NULL;
}

int main(int argc,char ** argv)
{
    /* 用于保存线程的线程号 */
    pthread_t p_tid;
    pthread_t c_tid;
    int i;
   
    re_buf.head=0;
    re_buf.tail=0;
    for(i=0;i<BUFSIZE;i++)
        re_buf.buffer[i] =0;
   
    /* 初始化可写资源数为循环队列的单元数 */
    sem_init(&write_res_number,0,BUFSIZE);    //  这里限定了可写的bufsize,当写线程写满buf时,会阻塞,等待读线程读取
    /* 初始化可读资源数为0 */
    sem_init(&read_res_number,0,0);
   
    /* 创建两个线程,线程函数分别是 producer 和 consumer */
    /* 这两个线程将使用系统的缺省的线程设置,如线程的堆栈大小、线程调度策略和相应的优先级等等*/
    pthread_create(&p_tid,NULL,producer,NULL);
    pthread_create(&c_tid,NULL,consumer,NULL);
   
    /*等待两个线程完成退出*/
    pthread_join(p_tid,NULL);
    pthread_join(c_tid,NULL);
    printf("The sun of number is %d\n",sum_of_number);
}

 

编译命令:gcc -g -o threadtest threadtest.c -lpthread

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics