標準Cによる信号量管理構造体Semaphore

4802 ワード

一、縁起
暇な慌てて、技術のブログを書いて、C言語を熟知します.ちなみに、この記事で実現したSemaphoreはLinuxでしか使用できませんが、Windowsプラットフォームについても同様の考え方で実現しています.この構造体の役割は,プログラムで多くの信号量を用いる場合に,各信号量の混同を回避するために,C++のようなクラスで変調することである.
二、実現
1、信号量メカニズムの概要
2、実現
コードを入れて、詳しいコメントが入っています.
//Semaphore.h
#include 

typedef struct Semaphore {
    char name[200];//        ,   200   ,      
    sem_t _sem;    //     ,      
    struct Semaphore *this;//       ,    ,    

    //       ,           ,      ,           。
    void (*init)(struct Semaphore *sem,char name[], unsigned value);
    void (*wait)(struct Semaphore *sem);
    void (*wait_time)(struct Semaphore *sem,int ms);
    void (*signal)(struct Semaphore *sem);
    void (*destroy)(struct Semaphore *sem);
}Semaphore;

//            
void init_semaphore(Semaphore *sem);
//            
Semaphore *get_semaphore();
 

 
//Semaphore.c
#include 
#include 
#include 
#include 
#include "Semaphore.h"

/**
 *       
 * @param name
 */
void init(Semaphore *sem,char name[], unsigned value) {
    strcpy(sem->name,name);
    sem_init(&(sem->_sem), 0, value);
}

/**
 *            P  .
 *     ,       ,             .
 */
void wait(Semaphore *sem) {
    sem_wait(&(sem->_sem));
}

/**
 *            P  .
 *     ,       ,             .
 *          ms    ,         .
 * @param ms     (ms)
 */
void wait_time(Semaphore *sem,int ms) {
    struct timespec t;
    t.tv_sec = ms / 1000;
    t.tv_nsec = (ms % 1000) * 1000;
    sem_timedwait(&(sem->_sem), &t);
}

/**
 *         ,         ,   
 *         V  .      .
 */
void signal(Semaphore *sem) {
    sem_post(&(sem->_sem));
}

/**
 *      
 */
void destroy(Semaphore *sem) {
    sem_destroy(&(sem->_sem));
    free(sem);
    sem = NULL;
}

/**
 *          
 * @param sem         
 */
void init_semaphore(Semaphore *sem) {
    sem->this = sem;
    sem->init = init;
    sem->wait = wait;
    sem->wait_time = wait_time;
    sem->signal = signal;
    sem->destroy = destroy;
}

/**
 *       
 * @return             
 */
Semaphore *get_semaphore() {
    Semaphore *sem;
    sem = (Semaphore *)malloc(sizeof(Semaphore));
    if(sem == NULL){
        printf("      ,    ...");
        exit(-1);
    }

    sem->this = sem;
    sem->init = init;
    sem->wait = wait;
    sem->wait_time = wait_time;
    sem->signal = signal;
    sem->destroy = destroy;

    return sem;
}


使用:単純な生産者---消費者モデル
//main.c
#include "Semaphore.h"
#include 
#include 
#include 
#include 

struct Goods{
    int id;//  id
};//  

Semaphore *g_sem;//   

struct Goods g_goods;//    

pthread_mutex_t g_mutex;//   

/**
 *        ,    
 * @param arg    
 * @return    
 */
void *producer(void *arg){

    int i=0;
    while (++i<5*5) {
        //        ,      
        sleep((unsigned)rand()%3+1);
        //    
        pthread_mutex_lock(&g_mutex);
        g_goods.id = rand()%1000;
        printf("    :%d
",g_goods.id); pthread_mutex_unlock(&g_mutex); // g_sem->signal(g_sem->this); } } /** * * @param arg * @return */ void *costumer(void *arg){ int i=0; int id = *((int *)arg); while (++i<5) { // , g_sem->wait(g_sem->this); // pthread_mutex_lock(&g_mutex); printf(" %d :%d
",id,g_goods.id); pthread_mutex_unlock(&g_mutex); } } int main() { // g_sem = get_semaphore(); // g_sem->init(g_sem->this,"sem", 0); // printf("sem name:%s
",g_sem->name); // srand((unsigned)time(NULL)); // pthread_mutex_init(&g_mutex,NULL); pthread_t producer_t; // pthread_t costumer_t[5];//5 // pthread_create(&producer_t,NULL,producer,NULL); // for(int i=0;i<5;i++){ pthread_t p; costumer_t[i] = p; pthread_create(&(costumer_t[i]),NULL,costumer,(void *)&i); } // pthread_join(producer_t,NULL); // for(int i=0;i<5;i++){ pthread_join(costumer_t[i],NULL); } // pthread_mutex_destroy(&g_mutex); // g_sem->destroy(g_sem->this); return 0; }

コンパイルコマンド:
gcc main.c Semaphore.c -o main -l pthread

最後にアンリは自分で書いたマルチスレッドプログラミングモデルで、とても簡単で使いやすいです!
https://github.com/Mannix1994/ThreadPool