zoukankan      html  css  js  c++  java
  • 线程同步那点事儿之semaphore+barrier的应用

    使用线程来模拟舞厅中的舞者。每个线程代表舞厅里穿着彩色裙子的人。舞厅里有一个主舞台。然而。只有三人一组的舞者才可以上主舞台。进入主舞台的第二个要求是,两名舞者必须穿红色的裙子,另一名舞者必须穿白色的裙子。

    在下面的程序中,每个线程在生成后调用对应于其颜色的函数。即有红色裙子的线程调用红色函数,有白色裙子的线程调用白色函数。

    你的任务是添加同步代码到红色和白色,这样他们阻塞,直到三个线程一起进入主舞台,然后函数应该返回。假设两个红色线程被红色线程阻塞,然后一个白色线程调用白色线程,第三个线程应该唤醒其他两个线程,它们都应该返回。

    #include <stdio.h>
    #include <pthread.h>
    
    #define NWHITE (1000)
    #define NRED   (NWHITE * 2)
    
    void read(void);
    void white(void);
    
    void* red(void *arg) {
        // TODO
        red();
        return NULL;
    }
    
    void* white(void *arg) {
        // TODO
        white();
        return NULL;
    }
    
    int main(void) {
        pthread_t thread_ids[NRED + NWHITE];
    
        for (size_t i = 0; i < NWHITE; ++i) {
            pthread_create(thread_ids + i * 3 + 0, NULL, red, NULL);
            pthread_create(thread_ids + i * 3 + 1, NULL, red, NULL);
            pthread_create(thread_ids + i * 3 + 2, NULL, white, NULL);
        }
    
        for (size_t i = 0; i < NRED + NWHITE; ++i) {
            pthread_join(thread_ids[i], NULL);
        }return 0;
    }

    利用信号量和barrier来实现:

    实现后代码如下:

    #include <stdio.h>
    #include <pthread.h>
    #include <semaphore.h>
    
    #define NWHITE (1000)
    #define NRED   (NWHITE * 2)
    
    sem_t red_pairs;
    sem_t white_mutex;
    pthread_barrier_t stage;
    
    void read(void);
    void white(void);
    
    void* red(void *arg) {
    
        // Using a semaphore that allows only two red threads to enter
        // Using a barrier to wait for the white thread to enter
    
        sem_wait(&red_pairs);
        pthread_barrier_wait(&stage);
        sem_post(&red_pairs);
        red();
        return NULL;
    }
    
    void* white(void *arg) {
    
        // Using a mutex that allows only one white thread to enter
        // Using a barrier to wait for the other two red threads
    
        sem_wait(&white_mutex);
        pthread_barrier_wait(&stage);
        sem_post(&white_mutex);
        white();
        return NULL;
    }
    
    int main(void) {
    
        sem_init(&red_pairs, 0, 2);
        sem_init(&white_mutex, 0, 1);
        pthread_barrier_init(&stage, NULL, 3);
    
        pthread_t thread_ids[NRED + NWHITE];
    
        for (size_t i = 0; i < NWHITE; ++i) {
            pthread_create(thread_ids + i * 3 + 0, NULL, red, NULL);
            pthread_create(thread_ids + i * 3 + 1, NULL, red, NULL);
            pthread_create(thread_ids + i * 3 + 2, NULL, white, NULL);
        }
    
        for (size_t i = 0; i < NRED + NWHITE; ++i) {
            pthread_join(thread_ids[i], NULL);
        }
    
        pthread_barrier_destroy(&stage);
    
        return 0;
    }
    每一个不曾起舞的日子里都是对以往生命的辜负!!
  • 相关阅读:
    磁盘冗余 ---RAID磁盘管理
    linux磁盘管理
    linux基础命令
    Apache配置rewrite
    memcache运维整理
    mysql主从配置
    rsync相关整理
    Lua 学习笔记(六)
    Lua 学习笔记(五)
    Lua 学习笔记(四)
  • 原文地址:https://www.cnblogs.com/whc-uestc/p/14905932.html
Copyright © 2011-2022 走看看