#创作灵感#
没有找到现成代码,只有自己写了; 写都写了,花了我一天的时间,不发白不发; 可能还有bug,私聊我,但不一定改,因为我懒; 别骂我,我玻璃心,骂我我就去钟楼顶上哭; 哪位大佬写了计图的作业,share一下,真做不完了。
Target
Write a c/c++ program To implement product and consumer problem using multi-threads GCC
Tools
Install GCC Software Collection
How to do
write a c program to implement product and consumer problem using multi-threads 实现I个⽣产者J个消费者问题,其中共享缓冲区的⼤⼩为N,所有⽣产者共⽣产K(K>N)个产品后结束,所有消费者共消费K个产品后结束。 具体要求
严格按时序输出每个⽣产者、消费者的⾏为,其中包括⽣产产品k、消费产品k、进⼊临界区、存⼊产品、取出产品、离开临界区; 需要考虑边界(某⽣产者⽣产第K个产品后所有⽣产者结束;某消费者消费第K个产品后所有消费者结束) 需要考虑随机函数,⽣产者⽣产时需要⼀个随机时间;消费者消费时也需要⼀个随机时间; 编号:⽆论⽣产者还是消费者都需要有编号;产品同样也需要编号;缓冲区的各个产品项也需要有编号; 输出形式可以采⽤标准输出、图形动态显⽰及同时⽂字记录输出等⽅式,⽆论是⽣产者还是消费者,其主要输出内容如下︓ a) 进⼊临界区前,输出某某编号(⽣产者/消费者)线程准备进⼊临界区 b) 进⼊临界区后,输出某某编号(⽣产者/消费者)线程已进⼊临界区 c) 离开临界区后,输出某某编号(⽣产者/消费者)线程已离开临界区 d) ⽣产者⽣产⼀个产品时,需要输出产品信息︔ e) ⽣产者将产品放⼊缓冲区时,需要输出相关信息︔ f) 消费者将产品从缓冲区取出时,需要输出相关信息︔ g) 消费者消费⼀个产品时,需要输出产品信息; 不能出现竞态 不能出现忙等待
参考代码(建议改一改参数,一定程度上借鉴了GPT)
# include <pthread.h>
# include <semaphore.h>
# include <stdlib.h>
# include <time.h>
# include <stdio.h>
# include <jmorecfg.h>
# include <unistd.h>
# define I 5
# define J 20
# define N 10
# define K 100
# define P_MAX_TIME 5
# define C_MAX_TIME 10
# define DATA_SIZE 256
typedef struct item_st {
int id;
int uid;
time_t timestamp_p;
int produce_id;
unsigned long checksum;
unsigned long data[ DATA_SIZE] ;
} ITEM_ST;
typedef struct buffer_st {
int id;
boolean isempty;
ITEM_ST item;
pthread_mutex_t mutex;
struct buffer_st * nextbuf;
} BUFFER_ST;
BUFFER_ST* g_buffer_head = NULL ;
int g_producer_count = I;
int g_consumer_count = J;
int produce_count = 0 ;
int consume_count = 0 ;
pthread_mutex_t g_count_mutex = PTHREAD_MUTEX_INITIALIZER;
sem_t g_empty_sem;
sem_t g_full_sem;
void produce_item ( ITEM_ST* item) {
item-> id = rand ( ) % 1000 ;
item-> uid = produce_count;
}
void * producer_thread ( void * arg) {
int id = * ( int * ) arg;
while ( 1 ) {
int sleep_time = rand ( ) % P_MAX_TIME;
sleep ( sleep_time) ;
printf ( "---- a) 进⼊临界区前,输出 %d 编号 ⽣产者 线程准备进⼊临界区;\n" , id) ;
sem_wait ( & g_empty_sem) ;
pthread_mutex_lock ( & g_buffer_head-> mutex) ;
printf ( "------ b) 进⼊临界区后,输出 %d 编号 ⽣产者 线程已进⼊临界区;\n" , id) ;
if ( produce_count >= K) {
pthread_mutex_unlock ( & g_buffer_head-> mutex) ;
sem_post ( & g_full_sem) ;
break ;
}
while ( g_buffer_head-> isempty == 0 ) {
g_buffer_head = g_buffer_head-> nextbuf;
}
pthread_mutex_lock ( & g_count_mutex) ;
produce_count++ ;
ITEM_ST item;
produce_item ( & item) ;
item. produce_id = id;
printf ( "-------- d) ⽣产者⽣产⼀个产品时,需要输出产品信息:uid: %d, proid: %d;\n" , item. uid, item. produce_id) ;
pthread_mutex_unlock ( & g_count_mutex) ;
g_buffer_head-> item = item;
g_buffer_head-> isempty = 0 ;
printf ( "---------- e) ⽣产者将产品放入缓冲区时,需要输出相关信息:%d 号 生产者 将 %d 号产品放入缓冲区;\n" , id, item. uid) ;
g_buffer_head = g_buffer_head-> nextbuf;
pthread_mutex_unlock ( & g_buffer_head-> mutex) ;
sem_post ( & g_full_sem) ;
printf ( "------------ c) 离开临界区后,输出 %d 编号 ⽣产者 线程已离开临界区;\n" , id) ;
}
return NULL ;
}
void * consumer_thread ( void * arg) {
int id = * ( int * ) arg;
while ( consume_count < K) {
while ( consume_count >= produce_count) {
sleep ( 1 ) ;
}
sem_wait ( & g_full_sem) ;
pthread_mutex_lock ( & g_buffer_head-> mutex) ;
while ( g_buffer_head-> isempty == 1 ) {
g_buffer_head = g_buffer_head-> nextbuf;
}
ITEM_ST item = g_buffer_head-> item;
g_buffer_head-> isempty = 1 ;
printf ( "++++++++++ f) 消费者将产品从缓冲区取出时,需要输出相关信息:%d 号 消费者 将 %d 号产品从缓冲区取出;\n" , id, item. uid) ;
pthread_mutex_lock ( & g_count_mutex) ;
consume_count++ ;
pthread_mutex_unlock ( & g_count_mutex) ;
int t_uid = item. uid;
int t_produce_id = item. produce_id;
g_buffer_head = g_buffer_head-> nextbuf;
pthread_mutex_unlock ( & g_buffer_head-> mutex) ;
sem_post ( & g_empty_sem) ;
int sleep_time = rand ( ) % C_MAX_TIME + 10 ;
sleep ( sleep_time) ;
printf ( "++++++++ g) 消费者消费⼀个产品时,需要输出产品信息:uid: %d, proid: %d;\n" , t_uid, t_produce_id) ;
}
return NULL ;
}
int main ( ) {
srand ( time ( NULL ) ) ;
BUFFER_ST* prev_buf = NULL ;
for ( int i = 0 ; i < N; i++ ) {
BUFFER_ST* buf = ( BUFFER_ST* ) malloc ( sizeof ( BUFFER_ST) ) ;
buf-> id = i;
buf-> isempty = 1 ;
if ( prev_buf != NULL ) {
prev_buf-> nextbuf = buf;
} else {
g_buffer_head = buf;
}
pthread_mutex_init ( & buf-> mutex, NULL ) ;
prev_buf = buf;
}
prev_buf-> nextbuf = g_buffer_head;
sem_init ( & g_empty_sem, 0 , N) ;
sem_init ( & g_full_sem, 0 , 0 ) ;
pthread_t producer_threads[ g_producer_count] ;
pthread_t consumer_threads[ g_consumer_count] ;
int producer_ids[ g_producer_count] ;
int consumer_ids[ g_consumer_count] ;
for ( int i = 0 ; i < g_producer_count; i++ ) {
producer_ids[ i] = i;
pthread_create ( & producer_threads[ i] , NULL , producer_thread, ( void * ) & producer_ids[ i] ) ;
}
sleep ( 10 ) ;
for ( int i = 0 ; i < g_consumer_count; i++ ) {
consumer_ids[ i] = i;
pthread_create ( & consumer_threads[ i] , NULL , consumer_thread, ( void * ) & consumer_ids[ i] ) ;
}
for ( int i = 0 ; i < g_producer_count; i++ ) {
pthread_join ( producer_threads[ i] , NULL ) ;
}
for ( int i = 0 ; i < g_consumer_count; i++ ) {
pthread_join ( consumer_threads[ i] , NULL ) ;
}
pthread_mutex_destroy ( & g_count_mutex) ;
sem_destroy ( & g_empty_sem) ;
sem_destroy ( & g_full_sem) ;
BUFFER_ST* curr_buf = g_buffer_head;
while ( curr_buf-> nextbuf != g_buffer_head) {
BUFFER_ST* next_buf = curr_buf-> nextbuf;
pthread_mutex_destroy ( & curr_buf-> mutex) ;
free ( curr_buf) ;
curr_buf = next_buf;
}
pthread_mutex_destroy ( & curr_buf-> mutex) ;
free ( curr_buf) ;
return 0 ;
}