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

    本次使用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;
}

猜你喜欢

转载自blog.csdn.net/dailongjian2008/article/details/51983640