📅  最后修改于: 2023-12-03 15:21:40.634000             🧑  作者: Mango
二进制信号量是一种利用二进制值来控制多个进程协同工作的机制。它只有两个取值:1和0,分别表示资源可用和资源不可用。当一个进程需要访问某个共享资源时,它首先需要检查信号量的值是否为1。如果是,表示资源空闲,进程可以获取该资源并将信号量的值设为0;否则表示资源已被其他进程占用,该进程只能等待。当其他进程释放资源后,它们会唤醒等待的进程,使其重新检查信号量的值并争夺资源。
二进制信号量主要用于进程间同步和互斥,特别是在生产者-消费者模型中经常使用。它的优点是实现简单,只需要一次赋值操作即可控制多个进程;缺点是不支持多个进程同时访问资源,因此在某些场景下可能会出现饥饿或死锁现象。
互斥量是一种用于保护共享资源不会被多个线程同时访问的机制。它可以被看作是一种计数信号量,只有两种值:0和1。当一个线程要访问某个共享资源时,它需要先尝试获取互斥量。如果互斥量的值为0,表示该资源已被其他线程占用,该线程则会进入阻塞状态直至互斥量的值变为1;否则表示该资源空闲,该线程可以获取该资源并将互斥量的值设为0。当线程使用完共享资源后,它必须释放互斥量,使其值变为1,以便其他线程可以继续访问该资源。
互斥量可以保证共享资源在任意时刻只能被一个线程访问,从而避免了竞态条件和数据不一致的问题。它的优点是支持多个线程同时访问资源,且可以避免饥饿和死锁现象;缺点是实现相对复杂,需要注意加锁和解锁的时机,否则可能会导致线程无法释放资源或者导致资源竞争。
二进制信号量适用于以下场景:
互斥量适用于以下场景:
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#define MAX_COUNT 10
sem_t bin_sem;
void *producer(void *arg)
{
int i;
for (i = 0; i < MAX_COUNT; i++) {
sem_wait(&bin_sem);
printf("Producer: produce item %d\n", i);
sem_post(&bin_sem);
}
pthread_exit(NULL);
}
void *consumer(void *arg)
{
int i;
for (i = 0; i < MAX_COUNT; i++) {
sem_wait(&bin_sem);
printf("Consumer: consume item %d\n", i);
sem_post(&bin_sem);
}
pthread_exit(NULL);
}
int main()
{
pthread_t tid_producer, tid_consumer;
sem_init(&bin_sem, 0, 1);
pthread_create(&tid_producer, NULL, producer, NULL);
pthread_create(&tid_consumer, NULL, consumer, NULL);
pthread_join(tid_producer, NULL);
pthread_join(tid_consumer, NULL);
sem_destroy(&bin_sem);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX_COUNT 10
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *worker(void *arg)
{
int i;
for (i = 0; i < MAX_COUNT; i++) {
pthread_mutex_lock(&mutex);
printf("Worker: process item %d\n", i);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main()
{
pthread_t tid_worker1, tid_worker2;
pthread_create(&tid_worker1, NULL, worker, NULL);
pthread_create(&tid_worker2, NULL, worker, NULL);
pthread_join(tid_worker1, NULL);
pthread_join(tid_worker2, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
以上示例代码可以在Linux平台上编译运行,需要链接pthread
库和rt
库(只有使用semaphore.h
头文件时需要)。