leetcode—— 交替打印FooBar

交替打印FooBar

方案一:

核心要点:

  • 用两把互斥锁
  • foo执行完后,释放bar的锁,bar执行完后,释放foo的锁

代码上来看,整体比较简洁,但效率不高

typedef struct {
    int n;
    pthread_mutex_t mutex1;  
    pthread_mutex_t mutex2;  
} FooBar;

FooBar* fooBarCreate(int n) {
    FooBar* obj = (FooBar*) malloc(sizeof(FooBar));
    obj->n = n;
    pthread_mutex_init(&obj->mutex1, NULL);
    pthread_mutex_init(&obj->mutex2, NULL);
    return obj;
}

void foo(FooBar* obj) {
    
    for (int i = 0; i < obj->n; i++) {
        pthread_mutex_lock(&obj->mutex1);
        // printFoo() outputs "foo". Do not change or remove this line.
        printFoo();
        pthread_mutex_unlock(&obj->mutex2);
    }
}

void bar(FooBar* obj) {
    
    for (int i = 0; i < obj->n; i++) {
        pthread_mutex_lock(&obj->mutex2);
        // printBar() outputs "bar". Do not change or remove this line.
        printBar();
        pthread_mutex_unlock(&obj->mutex1);
    }
}

void fooBarFree(FooBar* obj) {
    if (NULL != obj) {}
        pthread_mutex_destroy(&obj->mutex1);
        pthread_mutex_destroy(&obj->mutex2);
        free(obj);
}

方案二

核心要点:

  • 通过pthread_mutex_lock让两个线程互锁。
  • 构造一个判断条件,当不满足判断条件时,通过pthread_cond_wait让线程停在条件变量上,等待另外一个线程唤醒。
  • 判断条件满足后,修改判断条件的值foo打印后,通过pthread_cond_signal()通知bar线程打印。bar打印后,通过pthread_cond_signal()通知foo线程打印。

pthread_cond_wait内部的操作顺序是将线程放到等待队列,之后解锁,等条件满足时进行加锁,再返回。

  • 线程放在等待队列上,解锁
  • 等待 pthread_cond_signal或者pthread_cond_broadcast信号之后去竞争锁
  • 若竞争到互斥索则加锁。

通知函数有pthread_cond_signal和pthread_cond_broadcast,函数的名字已经充分说明了他们之间的区别。

typedef struct {
    int n;
    bool flag;
    pthread_mutex_t mutex;  
    pthread_cond_t  cond;  
} FooBar;

FooBar* fooBarCreate(int n) {
    FooBar* obj = (FooBar*) malloc(sizeof(FooBar));
    obj->n = n;
    obj->flag = true;
    pthread_mutex_init(&obj->mutex, NULL);
    pthread_cond_init(&obj->cond,NULL);
    return obj;
}

void foo(FooBar* obj) {
    
    for (int i = 0; i < obj->n; i++) {
        pthread_mutex_lock(&obj->mutex);
        while (false == obj->flag) {
            pthread_cond_wait(&obj->cond,&obj->mutex);
        }
        // printFoo() outputs "foo". Do not change or remove this line.
        printFoo();
        obj->flag = false;
        pthread_cond_signal(&obj->cond);
        pthread_mutex_unlock(&obj->mutex);
    }
}

void bar(FooBar* obj) {
    
    for (int i = 0; i < obj->n; i++) {
        pthread_mutex_lock(&obj->mutex);
        while (true == obj->flag) {
            pthread_cond_wait(&obj->cond,&obj->mutex);
        }
        // printBar() outputs "bar". Do not change or remove this line.
        printBar();
        obj->flag = true;
        pthread_cond_signal(&obj->cond);
        pthread_mutex_unlock(&obj->mutex);
    }
}

void fooBarFree(FooBar* obj) {
    if (NULL != obj) {}
        pthread_mutex_destroy(&obj->mutex);
        pthread_cond_destroy(&obj->cond);
        free(obj);
}

猜你喜欢

转载自www.cnblogs.com/beimangshanxiaoqigui/p/12502647.html
今日推荐