linux多线程编程实例

对象 操作 Linux Pthread API Windows SDK 库对应 API
线程 创建 pthread_create CreateThread
退出 pthread_exit ThreadExit
等待 pthread_join WaitForSingleObject
互斥锁 创建 pthread_mutex_init CreateMutex
销毁 pthread_mutex_destroy CloseHandle
加锁 pthread_mutex_lock WaitForSingleObject
解锁 pthread_mutex_unlock ReleaseMutex
条件 创建 pthread_cond_init CreateEvent
销毁 pthread_cond_destroy CloseHandle
触发 pthread_cond_signal SetEvent
广播 pthread_cond_broadcast SetEvent / ResetEvent
等待 pthread_cond_wait / pthread_cond_timedwait SingleObjectAndWait

功能:生产者生产按顺序依次生产16辆汽车,同时工厂只能存放16辆汽车;消费者按顺序依次提取那16辆汽车。在汽车生产满16辆时,停止生产,直到消费者提取汽车,有空的位置存放汽车才能开始生产汽车。

方案:建立一个结构体存储汽车数量及位置,互斥锁,空满信号struct prodcons buffer

          建立两个线程:一个是生产者生产汽车producer(),一个是消费者提取汽车consumer();

          建立两个函数:一个用来生产汽车put(),另一个用来提取汽车get();

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<pthread.h>

#define OVER (-1)
#define BUFFER_SIZE 16
struct prodcons buffer;

/*    设置一个整数的圆形缓冲区   */
struct prodcons{
        int buffer[BUFFER_SIZE]; /* 缓冲去数组*/
        pthread_mutex_t lock;    /* 互斥锁 */
        int readpos,writepos;    /* 读写的位置*/
        pthread_cond_t notempty;  /*缓冲区的非空信号*/
        pthread_cond_t notfull;   /*缓冲区非满信号*/

};


/*    初始化缓冲信号*/
void init(struct prodcons *b)
{
        pthread_mutex_init(&b->lock,NULL);
        pthread_cond_init(&b->notempty,NULL);
        pthread_cond_init(&b->notfull,NULL);
        b->readpos = 0;
        b->writepos = 0;
}

/*    向缓冲区写入一个整数*/
void put(struct prodcons *b,int data)
{
        pthread_mutex_lock(&b->lock);
       /*      等待缓冲区非满 */
        while((b->writepos +1)%BUFFER_SIZE == b->readpos){    
/*当缓冲区的位置56789...15, 1234存在信息  而readpos位于缓冲区的第5位置,此时缓冲区的所有位置都写满了信息,需要等待readpos读取信息,防止writepos位于readpos之后,把未读取的信息覆盖掉。*/
                printf("wait for not full\n");
                pthread_cond_wait(&b->notfull,&b->lock);
        }
        /*  向缓冲区写入信息 ,写的位置后移一位              */
        b->buffer[b->writepos] = data;
        b->writepos++;
        if(b->writepos>=BUFFER_SIZE) b->writepos = 0;
        /*  发送有一个非空信号,之后解开互斥锁            */
        pthread_cond_signal(&b->notempty);
        pthread_mutex_unlock(&b->lock);

}

/*   从缓冲区读取数值             */
int get(struct prodcons *b){
        int data;
        pthread_mutex_lock(&b->lock);
        /*             */
        while(b->writepos == b->readpos){
                printf("wait for not empty\n");
                pthread_cond_wait(&b->notempty,&b->lock);
        }
        /*               */
        data = b->buffer[b->readpos];
        b->readpos++;
        if(b->readpos>=BUFFER_SIZE) b->readpos=0;
        /*           */
        pthread_cond_signal(&b->notfull);
        pthread_mutex_unlock(&b->lock);
        return data;
}


void *producer(void *data)
{
        int n;
        for(n=0;n<32;n++){
                printf("put->%d\n",n);
                put(&buffer,n);
                sleep(1);
        }
        put(&buffer,OVER);
        printf("producer stopped! \n");
        return NULL;

}

void *consumer(void *data)
{
        int d;
        while(1){
                d=get(&buffer);
                if(d==OVER) break;
                printf("\t%d->get\n",d);
                sleep(1);
        }

        printf("consumer stopped!\n");
        return NULL;
}
  /*---------------------------/*/
int main(void)
{
        pthread_t th_a,th_b;
        void *retval;
        init(&buffer);
        pthread_create(&th_a,NULL,producer,NULL);
        pthread_create(&th_b,NULL,consumer,NULL);

 /*  阻塞,等待建立的那两个线程的结束             */
        pthread_join(th_a,&retval);
        pthread_join(th_b,&retval);
        return 0;
}
                                                                                                                                                                                                                                                                                                                                                                                                                      

输出结果

put->0
	0->get
put->1
	1->get
put->2
	2->get
put->3
	3->get
put->4
	4->get
put->5
	5->get
put->6
	6->get
put->7
	7->get
put->8
	8->get
put->9
	9->get
put->10
	10->get
put->11
	11->get
put->12
	12->get
put->13
	13->get
put->14
	14->get
put->15
	15->get
put->16
	16->get
put->17
	17->get
put->18
	18->get
put->19
	19->get
put->20
	20->get
put->21
	21->get
put->22
	22->get
put->23
	23->get
put->24
	24->get
put->25
	25->get
put->26
	26->get
put->27
	27->get
put->28
	28->get
put->29
	29->get
put->30
	30->get
put->31
	31->get
producer stopped! 
consumer stopped!

将sleep()注释掉的结果

wait for not empty
put->0
put->1
put->2
put->3
put->4
put->5
put->6
put->7
put->8
put->9
put->10
put->11
put->12
put->13
put->14
put->15
wait for not full
	0->get
	1->get
	2->get
	3->get
	4->get
	5->get
	6->get
	7->get
	8->get
	9->get
	10->get
	11->get
	12->get
	13->get
	14->get
	15->get
wait for not empty
put->16
put->17
put->18
put->19
put->20
put->21
put->22
put->23
put->24
put->25
put->26
put->27
put->28
put->29
put->30
put->31
	16->get
wait for not full
	17->get
	18->get
	19->get
	20->get
	21->get
	22->get
	23->get
	24->get
	25->get
	26->get
	27->get
	28->get
	29->get
	30->get
	31->get
consumer stopped!
producer stopped! 

猜你喜欢

转载自blog.csdn.net/cxyzyywoaini/article/details/87549165