C语言线程同步算法优化:使用结构体封装缓冲区和同步机制

在6.5.1节的同步算法中,缓冲区定义、读写指针、信号量都是全局变量,管理有些混乱,也不太符合要尽量减少全局变量设置的编程规范。一种改进方法是将缓冲区及相关的变量包装到一个类型为sbuf_t的结构体类型变量中,将同步代码添加到sbuf_insertsbuf_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_insertsbuf_remove函数定义为操作sbuf_t类型变量的方法,这样我们就可以在生产者和消费者线程函数中直接调用它们,而不需要再添加任何同步代码。

这个改进后的代码更加清晰易懂,符合编程规范,也更加易于扩展和维护。

C语言线程同步算法优化:使用结构体封装缓冲区和同步机制

原文地址: https://www.cveoy.top/t/topic/neQs 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录