缓冲区初始状态:
read不等于write。
生产者写满:
write==read,即将写的地方为刚读取的位置,就是下一个位置还没有读,所以代表写满。
消费者读完:
read+1=write,即将读的地方为即将写入得位置,还没有写,就不能再读了,这里就代表读完。
//信号量模型#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <semaphore.h>//临界资源描述信息struct Data{int d [ 5 ] ; //环形缓冲区int ptr_read ; //已经读位置int ptr_write ; //即将写位置sem_t can_read ; //可读数据数目sem_t can_write ; //可写数据数目};struct Data data ;int length = 5 ;static int value = 0 ; //作为环形缓冲区的数据void init_data ( void ){data . ptr_read = 4 ;data . ptr_write = 0 ;sem_init ( & data . can_read , 0 , 0 );sem_init ( & data . can_write , 0 , length );}void * thread_consumer ( void * arg );void * thread_producter ( void * arg );int main (){init_data ();/************创建消费者和生产者线程*******************/pthread_t consumer , producter ;pthread_attr_t attr ;void * thread_result ;/***设置线程为脱离类型***/pthread_attr_init ( & attr );pthread_attr_setdetachstate ( & attr , PTHREAD_CREATE_DETACHED );/***创建消费者线程***/pthread_create ( & consumer , & attr , thread_consumer , NULL );/***创建生产者线程***/pthread_create ( & producter , & attr , thread_producter , NULL );while ( 1 ){sleep ( 2 );}}void * thread_consumer ( void * arg ){int count = 0 ;while ( 1 ){/****随机的消费数据使得问题适应性更广*****/int sleep_time = rand () % 3 ;sleep ( sleep_time );sem_wait ( & data . can_read ); //减少可读信号量printf ( "sub data is = %d \n " , data . d [( data . ptr_read + 1 ) % length ]); //读出数据data . ptr_read = ( data . ptr_read + 1 ) % length ; //更新已读位置sem_post ( & data . can_write ); //增加可写信号量}}void * thread_producter ( void * arg ){int count = 0 ;while ( 1 ){int sleep_time = rand () % 3 ;sleep ( sleep_time );int ret = sem_wait ( & data . can_write ); //减少可写信号量data . d [ data . ptr_write ] =++ value ; //写入新的值printf ( "------add data is = %d \n " , data . d [ data . ptr_write ]); //打印新生产的值data . ptr_write = ( data . ptr_write + 1 ) % length ; //更新即将写入的位置ret = sem_post ( & data . can_read ); //增加可读信号量}}//条件变量模型本文属于转载,原创地址http://blog.csdn.net/qq_695538007/article/details/42834541#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <semaphore.h>//临界资源描述信息struct Data{int d [ 5 ] ; //临界资源int ptr_read ; //已经读指针位置int ptr_write ; //即将写指针位置pthread_mutex_t mutex1 ;pthread_mutex_t mutex2 ;pthread_cond_t can_read ;pthread_cond_t can_write ;};static int value = 0 ;struct Data data ;int length = 5 ;void init_data ( void ){data . ptr_read = 4 ;data . ptr_write = 0 ;pthread_cond_init ( & data . can_read , NULL );pthread_mutex_init ( & data . mutex1 , NULL );pthread_cond_init ( & data . can_write , NULL );pthread_mutex_init ( & data . mutex2 , NULL );}void * thread_consumer ( void * arg );void * thread_producter ( void * arg );int main (){init_data ();/************创建消费者和生产者线程*******************/pthread_t consumer , producter ;pthread_attr_t attr ;void * thread_result ;/***设置线程为脱离类型***/pthread_attr_init ( & attr );pthread_attr_setdetachstate ( & attr , PTHREAD_CREATE_DETACHED );/***创建消费者线程***/pthread_create ( & consumer , & attr , thread_consumer , NULL );/***创建生产者线程***/pthread_create ( & producter , & attr , thread_producter , NULL );while ( 1 ){sleep ( 2 );}}void * thread_consumer ( void * arg ){sleep ( 3 ); //消费者先睡眠2s,让生产者生产数据while ( 1 ){/****随机的消费数据使得问题适应性更广*****/int sleep_time = rand () % 3 ;sleep ( sleep_time );pthread_mutex_lock ( & data . mutex1 );if (( data . ptr_read + 1 ) % length == data . ptr_write ) //即将读的位置还没有写好数据pthread_cond_wait ( & data . can_read , & data . mutex1 );printf ( "sub data:%d \n " , data . d [( data . ptr_read + 1 ) % length ]); //唤醒后即可读取数据data . ptr_read = ( data . ptr_read + 1 ) % length ; //更新已经读取指针位置pthread_cond_signal ( & data . can_write );pthread_mutex_unlock ( & data . mutex1 );}}void * thread_producter ( void * arg ){int count = 0 ;while ( 1 ){int sleep_time = rand () % 3 ;sleep ( sleep_time );pthread_mutex_lock ( & data . mutex2 );if ( data . ptr_write == data . ptr_read ) //生产者即将写的位置为消费者即将读的位置pthread_cond_wait ( & data . can_write , & data . mutex2 ); //等待消费者data . d [ data . ptr_write ] =++ value ; //写入数据printf ( "------add data:%d \n " , data . d [ data . ptr_write ]);data . ptr_write = ( data . ptr_write + 1 ) % length ; //写指针后移pthread_cond_signal ( & data . can_read ); //通知消费者pthread_mutex_unlock ( & data . mutex2 );}}//线程消息模型#include <stdio.h>#include <pthread.h>#include <signal.h>struct Data{int d [ 5 ];int ptr_write ; //将要写入数据的位置int ptr_read ; //已经读取过数据的位置int can_write ;int can_read ;};pthread_t thread1 , thread2 ;struct Data data ;int value = 0 ;int length = 5 ;void * producer ( void * pvoid ){int signum ;sigset_t sig ;sigemptyset ( & sig );sigaddset ( & sig , SIGUSR1 );pthread_sigmask ( SIG_BLOCK , & sig , NULL ); //设置该线程的信号屏蔽字为SIGUSR1data . d [ data . ptr_write ] =++ value ;printf ( "produce new data : %d \n " , data . d [ data . ptr_write ]);data . ptr_write = ( data . ptr_write + 1 ) % length ;while ( 1 ){sleep ( rand () % 3 ); //随机睡眠if ( data . ptr_write == data . ptr_read ){data . can_write = 0 ;sigwait ( & sig , & signum ); //睡眠等待SIGUSR1信号的到来}data . d [ data . ptr_write ] =++ value ;printf ( "produce new data : %d \n " , data . d [ data . ptr_write ]);data . ptr_write = ( data . ptr_write + 1 ) % length ;if ( data . can_read == 0 ){data . can_read = 1 ;pthread_kill ( thread2 , SIGUSR2 );}}}void * consumer ( void * pvoid ){sleep ( 1 );int signum ;sigset_t sig ;sigemptyset ( & sig );sigaddset ( & sig , SIGUSR2 );pthread_sigmask ( SIG_BLOCK , & sig , NULL ); //设置该线程的信号屏蔽字为SIGUSR2while ( 1 ){sleep ( rand () % 3 ); //随机睡眠if (( data . ptr_read + 1 ) % length == data . ptr_write ){data . can_read = 0 ;sigwait ( & sig , & signum ); //睡眠等待SIGUSR1信号的到来}printf ( "------consumer new data : %d \n " , data . d [( data . ptr_read + 1 ) % length ]);data . ptr_read = ( data . ptr_read + 1 ) % length ;if ( data . can_write == 0 ){data . can_write = 1 ;pthread_kill ( thread1 , SIGUSR1 );}}}void main (){data . ptr_read = 4 ;data . ptr_write = 0 ;data . can_read = 0 ;data . can_write = 1 ;struct sigaction act ;act . sa_handler = SIG_IGN ;sigemptyset ( & act . sa_mask );act . sa_flags = 0 ;sigaction ( SIGUSR1 , & act , 0 ); //设置信号SIGUSR1的处理方式忽略sigaction ( SIGUSR2 , & act , 0 ); //设置信号SIGUSR1的处理方式忽略pthread_create ( & thread1 , NULL , producer , NULL );pthread_create ( & thread2 , NULL , consumer , NULL );pthread_detach ( thread1 );pthread_detach ( thread2 );while ( 1 ){sleep ( 2 );}}
Linux 多线程同步生产者 消费者
最新推荐文章于 2024-08-05 15:50:11 发布