Linux 多线程同步生产者 消费者

 
  

缓冲区初始状态:

read不等于write。

生产者写满

write==read,即将写的地方为刚读取的位置,就是下一个位置还没有读,所以代表写满。

消费者读完:

read+1=write,即将读的地方为即将写入得位置,还没有写,就不能再读了,这里就代表读完。

//信号量模型
#include
#include
#include
#include
#include
//临界资源描述信息
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 ); //增加可读信号量
}
}
//条件变量模型
 
   
#include
#include
#include
#include
#include
//临界资源描述信息
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
#include
#include
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 ); //设置该线程的信号屏蔽字为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 ;
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 ); //设置该线程的信号屏蔽字为SIGUSR2
while ( 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 );
}
}

本文属于转载,原创地址http://blog.csdn.net/qq_695538007/article/details/42834541

你可能感兴趣的:(Linux,线程)