伟明部落格

Linux C多线程编程--使用信号量进行线程间的同步和互斥

--发布于 2024-11-09 10:06:25

下面是一个简单的示例,演示了在Linux C中如何使用信号量进行线程间的同步和互斥:

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

sem_t semaphore;
int shared_resource = 0;

void* thread1(void* arg) {
    printf("Thread 1: Waiting for semaphore\n");
    sem_wait(&semaphore);

    printf("Thread 1: Acquired semaphore\n");
    shared_resource++;
    printf("Thread 1: Updated shared resource: %d\n", shared_resource);

    sem_post(&semaphore);
    printf("Thread 1: Released semaphore\n");

    return NULL;
}

void* thread2(void* arg) {
    printf("Thread 2: Waiting for semaphore\n");
    sem_wait(&semaphore);

    printf("Thread 2: Acquired semaphore\n");
    shared_resource--;
    printf("Thread 2: Updated shared resource: %d\n", shared_resource);

    sem_post(&semaphore);
    printf("Thread 2: Released semaphore\n");

    return NULL;
}

int main() {
    pthread_t t1, t2;

    sem_init(&semaphore, 0, 1);

    pthread_create(&t1, NULL, thread1, NULL);
    pthread_create(&t2, NULL, thread2, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    sem_destroy(&semaphore);

    return 0;
}

在这个例子中,有两个线程:thread1和thread2。它们共享一个整数变量shared_resource,初始值为0。使用信号量semaphore来控制对shared_resource的访问。

在thread1中,线程首先等待信号量semaphore,然后获取到了信号量,表示可以访问shared_resource。thread1将shared_resource的值加1,并打印更新后的值。之后,它释放信号量,允许其他线程访问shared_resource。

在thread2中,线程同样等待信号量semaphore,然后获取到了信号量,表示可以访问shared_resource。thread2将shared_resource的值减1,并打印更新后的值。最后,它释放信号量,允许其他线程访问shared_resource。

主函数中创建了两个线程并等待它们执行完毕,然后销毁了信号量。

这个例子展示了如何使用信号量实现线程间的互斥访问和同步。通过对信号量的等待和释放操作,线程可以控制对共享资源的访问,避免了竞态条件(Race Condition)的发生。

区别

条件变量(Condition Variable)和信号量(Semaphore)是在并发编程中常用的同步机制,它们有以下几个主要区别:

  1. 功能不同:

    • 条件变量:条件变量用于线程间的等待和唤醒机制,它允许线程在某个条件满足之前等待,并在条件满足时被唤醒。条件变量通常与互斥器一起使用,用于实现复杂的线程同步和通信。
    • 信号量:信号量是一种用于控制并发访问资源的计数器。它用于保护共享资源,限制同时访问该资源的线程数量。线程可以通过操作信号量的值来进行等待和唤醒,从而控制资源的访问。
  2. 使用方式不同:

    • 条件变量:条件变量通常与互斥器(Mutex)一起使用。线程在等待条件满足时会释放互斥器的锁,并进入等待状态。当其他线程满足了条件并发出信号时,等待的线程被唤醒并重新获取互斥器的锁,然后继续执行。
    • 信号量:信号量通过操作其计数器的值来进行等待和唤醒。当计数器大于零时,线程可以继续执行。当计数器为零时,线程将被阻塞等待。其他线程可以通过增加或减少信号量的值来唤醒等待的线程。
  3. 用途不同:

    • 条件变量:条件变量主要用于线程间的等待和唤醒机制,它允许线程根据特定条件来同步执行。例如,当某个共享资源达到一个特定状态时,线程可以等待条件满足后再继续执行。
    • 信号量:信号量用于控制并发访问资源的数量。它可以限制同时访问共享资源的线程数量,从而实现对共享资源的保护和同步。

总结起来,条件变量主要用于线程间的等待和唤醒机制,通过等待特定条件的满足来实现线程的同步。而信号量用于控制并发访问资源的数量,通过对计数器的操作来实现线程的等待和唤醒,以及对共享资源的保护和同步。

--更新于 2024-11-09 10:09:00