当前位置:首页 > C > 正文

C语言信号量详解(小白也能掌握的多线程同步利器)

C语言信号量 的世界里,信号量(Semaphore)是一种非常重要的同步机制,用于控制多个线程或进程对共享资源的访问。无论你是刚接触 C语言并发编程 的新手,还是想深入理解 POSIX信号量 的开发者,本教程都将带你从零开始,一步步掌握信号量的核心概念和使用方法。

什么是信号量?

信号量本质上是一个整型变量,用来表示可用资源的数量。它支持两个原子操作:

  • wait()(也叫 P 操作):如果信号量值大于0,则减1;否则阻塞等待。
  • signal()(也叫 V 操作):将信号量值加1,并唤醒等待的线程。
C语言信号量详解(小白也能掌握的多线程同步利器) C语言信号量 POSIX信号量 多线程同步 C语言并发编程 第1张

POSIX 信号量类型

在 Linux 系统中,POSIX信号量 分为两类:

  1. 命名信号量(Named Semaphore):可通过名字在不相关的进程间共享。
  2. 未命名信号量(Unnamed Semaphore):通常用于同一进程内的线程间同步,或通过共享内存用于相关进程。

实战:使用未命名信号量实现线程同步

下面是一个简单的 C 语言示例,演示如何使用未命名信号量控制两个线程对共享变量的访问:

#include <stdio.h>#include <pthread.h>#include <semaphore.h>#include <unistd.h>sem_t sem;int shared_counter = 0;void* thread_func(void* arg) {    for (int i = 0; i < 5; i++) {        sem_wait(&sem); // P 操作:获取信号量        shared_counter++;        printf("Thread %ld: counter = %d\n", (long)arg, shared_counter);        sleep(1);        sem_post(&sem); // V 操作:释放信号量    }    return NULL;}int main() {    pthread_t t1, t2;    // 初始化未命名信号量,初始值为1(相当于互斥锁)    sem_init(&sem, 0, 1);    pthread_create(&t1, NULL, thread_func, (void*)1);    pthread_create(&t2, NULL, thread_func, (void*)2);    pthread_join(t1, NULL);    pthread_join(t2, NULL);    sem_destroy(&sem);    printf("Final counter value: %d\n", shared_counter);    return 0;}

编译时需链接 pthread 和 rt 库:

gcc -o semaphore_example semaphore.c -pthread

常见应用场景

C语言并发编程 中,信号量常用于以下场景:

  • 限制同时访问数据库连接池的线程数
  • 生产者-消费者模型中的缓冲区管理
  • 控制对有限硬件资源(如打印机)的并发访问

小结

通过本教程,你已经掌握了 C语言信号量 的基本原理和使用方法。无论是 POSIX信号量 还是更高级的同步机制,理解信号量都是迈向高效、安全 C语言并发编程 的关键一步。动手实践上面的代码,你会对多线程同步有更直观的感受!