📜  互斥与信号量(1)

📅  最后修改于: 2023-12-03 15:21:41.595000             🧑  作者: Mango

互斥与信号量

1. 什么是互斥?

互斥指的是在同一时刻只能有一个线程执行某一段代码,其他线程必须等待当前线程执行完毕才能继续执行。这种锁机制称为互斥锁(Mutex)。

在多线程环境下,对共享资源进行访问时,会引发多个线程访问同一个资源的问题。资源可能被多个线程同时使用导致数据的一致性问题,而互斥锁机制可以保证同一时刻只能有一个线程使用该共享资源,从而保证数据的一致性。

2. 什么是信号量?

信号量是一种计数器,用于多线程程序中控制进入某一程序段的线程数,或者控制同时访问某一共享资源的线程数。

信号量的值为正时表示资源可用,当值为零时表示资源已被占用,此时等待其它线程释放资源。信号量在多线程中常用于进程之间的同步和互斥操作。

3. 互斥与信号量的区别

互斥和信号量都是多线程编程中同步机制的一种,都可以用来控制对共享资源的访问。互斥只允许一个线程访问共享资源,使用一个锁机制实现,并且也被称为互斥锁。而信号量可以允许多个线程同时访问资源,并通过累积计数器的方式来实现。

互斥和信号量还有一个区别是,互斥只能在两个线程之间进行同步,而信号量可以用于线程之间、进程之间以及不同操作系统之间的同步。信号量也比互斥更加复杂,因为它需要计数器进行管理。

4. 使用互斥锁的示例代码
#include <stdio.h>
#include <pthread.h>

#define MAX 10
int sum = 0;
pthread_mutex_t lock;

void* add(void* arg) {
    int i;
    for (i = 0; i < MAX; i++) {
        pthread_mutex_lock(&lock);
        sum++;
        pthread_mutex_unlock(&lock);
    }
    return NULL;
}

int main() {
    pthread_t tid1, tid2;
    pthread_mutex_init(&lock, NULL);

    pthread_create(&tid1, NULL, add, NULL);
    pthread_create(&tid2, NULL, add, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    printf("Result: %d\n", sum);

    pthread_mutex_destroy(&lock);
    return 0;
}

在这个示例中,我们使用了互斥锁来保护共享变量sum。两个线程分别对sum加10次,由于互斥锁的作用,只有一个线程能够访问sum,避免了数据不一致的问题。

5. 使用信号量的示例代码
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define MAX 10
int count = 0;
sem_t sem;

void* add(void* arg) {
    int i;
    for (i = 0; i < MAX; i++) {
        sem_wait(&sem);
        count++;
        sem_post(&sem);
    }
    return NULL;
}

int main() {
    pthread_t tid1, tid2;
    sem_init(&sem, 0, 1);

    pthread_create(&tid1, NULL, add, NULL);
    pthread_create(&tid2, NULL, add, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    printf("Result: %d\n", count);

    sem_destroy(&sem);
    return 0;
}

在这个示例中,我们使用了信号量来保护共享变量count。由于信号量的作用,两个线程可以同时访问count,避免了数据不一致的问题。