生产者消费者问题
编译指令
| #include "csapp.h" |
| |
| #include<pthread.h> |
| #include<stdio.h> |
| #include<stdlib.h> |
| #include<unistd.h> |
| #include<time.h> |
| |
| pthread_cond_t cond = PTHREAD_COND_INITIALIZER; |
| pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
| |
| typedef struct node//链表结点 |
| { |
| int data; |
| struct node* next; |
| }node, *node_p, **node_pp; |
| |
| node_p getnode(int data) |
| { |
| node_p ret = malloc(sizeof(node)); |
| if(ret != NULL) |
| { |
| ret->data = data; |
| ret->next = NULL; |
| return ret; |
| } |
| return NULL; |
| } |
| |
| void initlist(node_pp pphead) |
| { |
| if(pphead == NULL) |
| exit(1); |
| *pphead = malloc(sizeof(node)); |
| (*pphead)->next = NULL; |
| } |
| |
| int isEmpty(node_p phead) |
| { |
| return (phead->next == NULL)?1:0; |
| } |
| |
| void push(node_p phead, int data) |
| { |
| node_p tmp = getnode(data); |
| if(tmp != NULL) |
| { |
| tmp->next = phead->next; |
| phead->next = tmp; |
| } |
| } |
| |
| void print(node_p phead) |
| { |
| phead = phead->next; |
| while(phead) |
| { |
| printf("%d ", phead->data); |
| phead = phead->next; |
| } |
| } |
| |
| void erase(node_p phead, int *x) |
| { |
| |
| if(isEmpty(phead)) |
| return; |
| node_p cur = phead->next; |
| phead->next = cur->next; |
| *x = cur->data; |
| free(cur); |
| } |
| |
| void destroy(node_p phead) |
| { |
| while(!isEmpty(phead)) |
| { |
| int data; |
| erase(phead, &data); |
| } |
| free(phead); |
| } |
| |
| void *producer(void* arg) |
| { |
| node_p phead = (node_p)arg; |
| while(1) |
| { |
| int data = rand()%1000; |
| pthread_mutex_lock(&mutex); |
| push(phead, data); |
| printf("producer done, %d\n", data); |
| pthread_mutex_unlock(&mutex); |
| pthread_cond_signal(&cond); |
| sleep(1); |
| } |
| } |
| |
| void* consumer(void* arg) |
| { |
| node_p phead = (node_p)arg; |
| int data = 0; |
| while(1) |
| { |
| pthread_mutex_lock(&mutex); |
| while(isEmpty(phead)) |
| { |
| printf("no product, please wait...\n"); |
| pthread_cond_wait(&cond, &mutex); |
| } |
| erase(phead, &data); |
| printf("consumer done, %d\n", data); |
| pthread_mutex_unlock(&mutex); |
| usleep(100000); |
| } |
| } |
| int main() |
| { |
| node_p phead; |
| initlist(&phead); |
| |
| srand((unsigned long)time(NULL)); |
| pthread_t t1, t2; |
| pthread_create(&t1, NULL, producer, (void*)phead); |
| pthread_create(&t2, NULL, consumer, (void*)phead); |
| |
| pthread_join(t1, NULL); |
| pthread_join(t2, NULL); |
| |
| destroy(phead); |
| pthread_mutex_destroy(&mutex); |
| pthread_cond_destroy(&cond); |
| return 0; |
| } |
读者写者问题
输入数据:
| 1 R 3 5 |
| 2 W 4 5 |
| 3 R 5 2 |
| 4 R 6 5 |
| 5 W 7 3 |
编译指令
运行指令
大概需要运行20s。
| #include <assert.h> |
| #include <pthread.h> |
| #include <unistd.h> |
| #include <semaphore.h> |
| #include <stdio.h> |
| |
| typedef struct { |
| int tid; |
| int delay; |
| int last; |
| } Role; |
| |
| enum { |
| s_waiting, |
| s_reading, |
| s_writing |
| } state = s_waiting; |
| |
| static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
| sem_t Sig_read; |
| sem_t Sig_wrt; |
| int reader_count = 0; |
| int writer_count = 0; |
| |
| time_t startTime; |
| |
| |
| void* reader(void* argPtr) { |
| Role role = *(Role*)argPtr; |
| sleep(role.delay); |
| printf("[%02.0lf秒]读者进程%d等待读取\n", |
| difftime(time(NULL), startTime), role.tid |
| ); |
| |
| pthread_mutex_lock(&mutex); |
| ++reader_count; |
| if(state == s_waiting |
| || (state == s_reading && writer_count == 0)) { |
| sem_post(&Sig_read); |
| state = s_reading; |
| } |
| pthread_mutex_unlock(&mutex); |
| sem_wait(&Sig_read); |
| |
| printf("[%02.0lf秒]读者进程%d开始读取\n", |
| difftime(time(NULL), startTime), role.tid |
| ); |
| |
| |
| sleep(role.last); |
| |
| pthread_mutex_lock(&mutex); |
| --reader_count; |
| if(writer_count != 0) { |
| |
| sem_post(&Sig_wrt); |
| state = s_writing; |
| } else if(reader_count == 0) { |
| |
| state = s_waiting; |
| } |
| pthread_mutex_unlock(&mutex); |
| |
| printf("[%02.0lf秒]读者进程%d读取结束\n", |
| difftime(time(NULL), startTime), role.tid |
| ); |
| return NULL; |
| } |
| |
| |
| void* writer(void* argPtr) { |
| Role role = *(Role*)argPtr; |
| sleep(role.delay); |
| printf("[%02.0lf秒]写者进程%d等待写入\n", |
| difftime(time(NULL), startTime), role.tid |
| ); |
| pthread_mutex_lock(&mutex); |
| ++writer_count; |
| if(state == s_waiting) { |
| sem_post(&Sig_wrt); |
| state = s_writing; |
| } |
| pthread_mutex_unlock(&mutex); |
| |
| sem_wait(&Sig_wrt); |
| printf("[%02.0lf秒]写者进程%d开始写入\n", |
| difftime(time(NULL), startTime), role.tid |
| ); |
| |
| sleep(role.last); |
| |
| pthread_mutex_lock(&mutex); |
| --writer_count; |
| if(writer_count != 0) { |
| sem_post(&Sig_wrt); |
| state = s_writing; |
| } else if(reader_count != 0) { |
| for(int i=0; i!=reader_count; ++i) { |
| sem_post(&Sig_read); |
| } |
| state = s_reading; |
| } else { |
| state = s_waiting; |
| } |
| pthread_mutex_unlock(&mutex); |
| |
| printf("[%02.0lf秒]写者进程%d写入结束\n", |
| difftime(time(NULL), startTime), role.tid |
| ); |
| return NULL; |
| } |
| |
| int main() { |
| const int MAX_THREAD = 100; |
| |
| pthread_t tid[MAX_THREAD]; |
| Role role[MAX_THREAD]; |
| int tidEnd = 0; |
| |
| |
| sem_init(&Sig_read, 0, 0); |
| sem_init(&Sig_wrt, 0, 0); |
| |
| startTime = time(NULL); |
| |
| int arg_tid; |
| int arg_delay; |
| int arg_last; |
| char arg_type; |
| while(scanf("%d %c%d%d", &arg_tid, &arg_type, &arg_delay, &arg_last) == 4) { |
| assert(tidEnd < MAX_THREAD); |
| if(arg_type == 'R') { |
| role[tidEnd].tid = arg_tid; |
| role[tidEnd].delay = arg_delay; |
| role[tidEnd].last = arg_last; |
| pthread_create(tid + tidEnd, NULL, reader, role + tidEnd); |
| } else { |
| role[tidEnd].tid = arg_tid; |
| role[tidEnd].delay = arg_delay; |
| role[tidEnd].last = arg_last; |
| pthread_create(tid + tidEnd, NULL, writer, role + tidEnd); |
| } |
| printf("[%02.0lf秒]创建进程%d\n", difftime(time(NULL), startTime), arg_tid); |
| ++tidEnd; |
| } |
| |
| for(int i=0; i!=tidEnd; ++i) { |
| pthread_join(tid[i], NULL); |
| } |
| |
| |
| pthread_mutex_destroy(&mutex); |
| sem_destroy(&Sig_read); |
| sem_destroy(&Sig_wrt); |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!