C语言线程同步算法优化:使用结构体封装缓冲区和同步机制
C语言线程同步算法优化:使用结构体封装缓冲区和同步机制
在6.5.1节的同步算法中,缓冲区定义、读写指针、信号量都是全局变量,管理有些混乱,也不太符合要尽量减少全局变量设置的编程规范。一种改进方法是将缓冲区及相关的变量包装到一个类型为sbuf_t的结构体类型变量中,将同步代码添加到sbuf_insert和sbuf_remove函数中,这样生产者和消费者线程函数就不需要任何同步代码了。
改进后的代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define MAX 10
typedef struct {
int buffer[MAX];
int in;
int out;
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
} sbuf_t;
void sbuf_init(sbuf_t *sp) {
sp->in = 0;
sp->out = 0;
sem_init(&sp->empty, 0, MAX);
sem_init(&sp->full, 0, 0);
pthread_mutex_init(&sp->mutex, NULL);
}
void sbuf_deinit(sbuf_t *sp) {
sem_destroy(&sp->empty);
sem_destroy(&sp->full);
pthread_mutex_destroy(&sp->mutex);
}
void sbuf_insert(sbuf_t *sp, int item) {
sem_wait(&sp->empty);
pthread_mutex_lock(&sp->mutex);
sp->buffer[sp->in] = item;
sp->in = (sp->in + 1) % MAX;
pthread_mutex_unlock(&sp->mutex);
sem_post(&sp->full);
}
int sbuf_remove(sbuf_t *sp) {
int item;
sem_wait(&sp->full);
pthread_mutex_lock(&sp->mutex);
item = sp->buffer[sp->out];
sp->out = (sp->out + 1) % MAX;
pthread_mutex_unlock(&sp->mutex);
sem_post(&sp->empty);
return item;
}
sbuf_t shared;
void *producer(void *arg) {
int i, item;
for (i = 0; i < 20; i++) {
item = rand() % 100;
sbuf_insert(&shared, item);
printf('Producer %u inserted %d\n', (unsigned int)pthread_self(), item);
}
pthread_exit(NULL);
}
void *consumer(void *arg) {
int i, item;
for (i = 0; i < 20; i++) {
item = sbuf_remove(&shared);
printf('Consumer %u removed %d\n', (unsigned int)pthread_self(), item);
}
pthread_exit(NULL);
}
int main() {
pthread_t producers[3], consumers[3];
int i;
sbuf_init(&shared);
for (i = 0; i < 3; i++) {
pthread_create(&producers[i], NULL, producer, NULL);
pthread_create(&consumers[i], NULL, consumer, NULL);
}
for (i = 0; i < 3; i++) {
pthread_join(producers[i], NULL);
pthread_join(consumers[i], NULL);
}
sbuf_deinit(&shared);
return 0;
}
改进后的代码说明
在这个改进后的代码中,我们定义了一个叫做sbuf_t的结构体类型,其中包含了缓冲区、读写指针以及信号量等所有相关变量。我们在sbuf_init函数中初始化这些变量,在sbuf_deinit函数中销毁它们。
我们把sbuf_insert和sbuf_remove函数定义为操作sbuf_t类型变量的方法,这样我们就可以在生产者和消费者线程函数中直接调用它们,而不需要再添加任何同步代码。
这个改进后的代码更加清晰易懂,符合编程规范,也更加易于扩展和维护。
原文地址: https://www.cveoy.top/t/topic/neQs 著作权归作者所有。请勿转载和采集!