当前位置:首页 > 系统教程 > 正文

深入浅出Linux POSIX信号量(从理论到实践)

深入浅出Linux POSIX信号量(从理论到实践)

深入浅出Linux POSIX信号量(从理论到实践) POSIX信号量 Linux线程同步 信号量函数 生产者消费者问题 第1张

在Linux系统编程中,POSIX信号量是一种用于进程或线程间同步的重要机制。本文将详细介绍POSIX信号量的概念、函数用法,并通过实例帮助读者掌握其应用。

1. 什么是信号量?

信号量是一个计数器,用于控制多个线程对共享资源的访问。它由Dijkstra提出,常用于解决同步问题,如生产者-消费者问题。POSIX信号量是POSIX标准定义的接口,易于使用且可移植。

2. POSIX信号量类型

POSIX信号量分为两种:有名信号量无名信号量。有名信号量通过名字在文件系统中可见,可用于不同进程间同步;无名信号量则仅存在于内存中,常用于线程间同步。

3. 常用函数

  • sem_open():创建或打开有名信号量。
  • sem_close():关闭有名信号量。
  • sem_unlink():删除有名信号量。
  • sem_init():初始化无名信号量。
  • sem_destroy():销毁无名信号量。
  • sem_wait():等待信号量,将其值减1,若为0则阻塞。
  • sem_post():释放信号量,将其值加1,唤醒等待线程。
  • sem_trywait():非阻塞版本。
  • sem_getvalue():获取当前值。

4. 示例:生产者-消费者问题

下面使用无名信号量实现一个简单的生产者-消费者模型,演示Linux线程同步

    #include #include #include #define BUFFER_SIZE 5int buffer[BUFFER_SIZE];int in = 0, out = 0;sem_t empty, full;pthread_mutex_t mutex;void* producer(void* arg) {    int item = 0;    while (1) {        item++;        sem_wait(&empty);        pthread_mutex_lock(&mutex);        buffer[in] = item;        printf("生产: %d at %d", item, in);        in = (in + 1) % BUFFER_SIZE;        pthread_mutex_unlock(&mutex);        sem_post(&full);        sleep(1);    }    return NULL;}void* consumer(void* arg) {    int item;    while (1) {        sem_wait(&full);        pthread_mutex_lock(&mutex);        item = buffer[out];        printf("消费: %d from %d", item, out);        out = (out + 1) % BUFFER_SIZE;        pthread_mutex_unlock(&mutex);        sem_post(&empty);        sleep(2);    }    return NULL;}int main() {    pthread_t prod, cons;    sem_init(&empty, 0, BUFFER_SIZE);    sem_init(&full, 0, 0);    pthread_mutex_init(&mutex, NULL);    pthread_create(&prod, NULL, producer, NULL);    pthread_create(&cons, NULL, consumer, NULL);    pthread_join(prod, NULL);    pthread_join(cons, NULL);    sem_destroy(&empty);    sem_destroy(&full);    pthread_mutex_destroy(&mutex);    return 0;}  

此例中,两个信号量emptyfull控制缓冲区的空位和满位,互斥锁保护缓冲区访问。这就是典型的生产者消费者问题实现。

5. 注意事项

  • 初始化信号量时指定初值,注意无名信号量的pshared参数决定是否用于进程间同步。
  • 使用sem_wait前确保信号量已初始化,避免死锁。
  • 使用完信号量后及时销毁,释放资源。
  • 有名信号量使用sem_open创建,路径名需符合规范。

6. 总结

POSIX信号量是Linux系统编程中强大的同步工具,掌握信号量函数的使用,能有效避免竞态条件,编写出健壮的多线程程序。希望本文能帮助读者入门POSIX信号量。