linux信号量实现线程读写同步

本文介绍如何使用Linux信号量实现线程间的读写同步,并通过调整信号量和临界区的处理顺序来避免死锁问题。通过具体代码示例展示了信号量初始化、线程创建及同步控制的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    本次使用linux信号量来实现线程读写同步,还是实现之前写的那个读和写数组的例子,本次在写的过程中出现一个死锁问题,原因是先进入临界区,然后等待信号量,这样造成读函数在等待信号量,写函数在等待进入临界区,所以修改了下程序,先进入信号量的等待,再进入临界区的等待,这也说明了我们写程序时不能长时间占用临界区,会很容易造成死锁。程序代码如下:
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>

#define MAX_NUM  100
#define MAX_THREAD 10

static int g_array[MAX_NUM];
volatile int g_num_gen = 0;
volatile int g_count = 0;
static int g_stop = 0;
static sem_t g_sem_full;
static sem_t g_sem_empty;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;

void *write_thread(void *arg)
{
    int i;
    while(!g_stop ){
        sem_wait(&g_sem_empty);
        pthread_mutex_lock(&g_mutex);
        if( g_stop ){
            break;
        }
        g_array[g_count++] = g_num_gen++;
        printf("write %d count=%d tid=%lu\n", g_array[g_count-1], g_count, pthread_self() );
        pthread_mutex_unlock(&g_mutex);
        sem_post(&g_sem_full);
        usleep(1000*500);
    }
    for(i=0; i<MAX_THREAD; i++){
        sem_post(&g_sem_full);
    }
    pthread_mutex_unlock(&g_mutex);

    return NULL;
}

void *read_thread(void *arg)
{
    int i;
    while(!g_stop ){
        sem_wait(&g_sem_full);
        pthread_mutex_lock(&g_mutex);
        if( g_stop ){
            break;
        }
        printf("read %d count=%d tid=%lu\n", g_array[g_count-1], g_count, pthread_self() );
        g_count--;
        pthread_mutex_unlock(&g_mutex);
        sem_post(&g_sem_empty);
        usleep(1000*500);
    }
    for(i=0; i<MAX_THREAD; i++){
        sem_post(&g_sem_empty);
    }
    pthread_mutex_unlock(&g_mutex);
    return NULL;
}


int main()
{
    int i;
    pthread_t *tid;
    void *thread_result;

    if (sem_init(&g_sem_full, 1,  0) == -1){
        fprintf( stderr, "Failed to initialize semaphore g_sem_full\n");
        return -1;
    }
    if( sem_init(&g_sem_empty, 1,  MAX_NUM) == -1 ){
        fprintf( stderr, "Failed to initialize semaphore g_sem_empty\n");
        return -1;
    }

    if ((tid = (pthread_t *)calloc(MAX_THREAD, sizeof(pthread_t))) == NULL) {
        perror("Failed to allocate space for thread IDs");
        return -1;
    }
    /* 开启写线程 */
    for(i=0; i<8; i++){
        pthread_create(tid+i, NULL, write_thread, 0 );
    }
    /* 开启读线程 */
    for(i=8; i<MAX_THREAD; i++) {
        pthread_create(tid+i, NULL, read_thread, 0 );
    }

    /* 由用户输入任意值,然后各个线程安全退出 */
    getchar();
    g_stop = 1;
    for(i=0; i<MAX_THREAD; i++ ){
        pthread_join(tid[i], &thread_result);
    }
    free(tid);
    sem_destroy(&g_sem_empty);
    sem_destroy(&g_sem_full);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值