-1

我编写了这个使用信号量而不是 pthread_cond 和 pthread_mutex 的小程序:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sema;

pthread_t threads[2];

pthread_cond_t cond;

pthread_mutex_t mutex;

int value;

void * worker_a();
void * worker_b();

int main() {
    value = 3;

    sem_init(&sema, 0, 0);

    pthread_create(&threads[1], NULL, worker_b, NULL);
    pthread_create(&threads[0], NULL, worker_a, NULL);

    pthread_join(threads[0], NULL);
    pthread_join(threads[1], NULL);

    pthread_detach(threads[0]);
    pthread_detach(threads[1]);

    sem_destroy(&sema);

    printf("Value has been set to: %d.\n", value);

    return 0;
}

/**
 * Multiplicates value by 4.
 */
void * worker_a() {
    value *= 4;

    sem_post(&sema);

    pthread_exit(NULL);
}

/**
 * Divides value by 2.
 */
void * worker_b() {
    sem_wait(&sema);

    value /= 2;

    sem_post(&sema);

    pthread_exit(NULL);
}

首先这个例子正确吗?我的意思是它可以正确编译和执行,但这可能只是因为程序过于简单。

第二:我是否正确理解使用信号量只是使用互斥锁、条件变量和许多条件标志的更聪明的替代方案?

博多

4

1 回答 1

1

不,鉴于您在评论中阐明的目标(value最终为 6),这是不正确的。worker_a和的执行顺序worker_b不能保证。

您对信号量的使用与使用普通互斥锁没有什么不同。它只是防止value并发操作,但不强制执行任何排序。在它抓住信号量之前把 a扔进sleep(5)worker_a,你就会明白我的意思了。

您可以将信号量初始化为零,并在worker_a完成后发布。然后worker_b会在正确的时间醒来做它的工作:

// main
// ----
   sem_init(&sema, 0, 0);  // N.B. initial value is ZERO

// worker_a
// --------
   value *= 4;             // We know a priori that sema is zero and others will wait for it
   sem_post(&sema);        // Let worker_b proceed

// worker_b
// --------
   sem_wait(&sema);        // Pause until worker_a is done
   value /= 2;
   sem_post(&sema);
于 2013-05-30T14:50:25.310 回答