欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > C语言中信号量:<semaphore.h>头文件

C语言中信号量:<semaphore.h>头文件

2025/5/6 14:49:02 来源:https://blog.csdn.net/jkzyx123/article/details/144564344  浏览:    关键词:C语言中信号量:<semaphore.h>头文件

<semaphore.h> 是一个 POSIX 标准定义的头文件,用于提供信号量(semaphore)的接口。信号量是用于线程或进程间同步的一种机制,可以控制访问共享资源的线程数目,广泛应用于多线程和多进程编程。

本文将详细介绍 <semaphore.h> 的数据类型、函数、以及示例。


1. 引入头文件

在使用信号量功能时,必须包含 <semaphore.h>

#include <semaphore.h>

2. 数据类型

sem_t

  • 信号量的主要数据类型。
  • 定义为一个结构体,用于存储信号量的当前值和相关信息。
  • 可以用于进程间或线程间的同步。

3. 函数及用途

以下是 <semaphore.h> 中的主要函数:

(1) 初始化与销毁信号量

函数描述
int sem_init(sem_t *sem, int pshared, unsigned int value);初始化一个信号量。
int sem_destroy(sem_t *sem);销毁一个信号量。
  • sem_init 参数说明
    • sem:指向信号量的指针。
    • pshared
      • 如果为 0,信号量用于线程间同步。
      • 如果为非 0,信号量用于进程间同步(需要位于共享内存中)。
    • value:信号量的初始值(代表资源数目)。
  • 返回值:成功返回 0,失败返回 -1

(2) 信号量操作

函数描述
int sem_wait(sem_t *sem);将信号量的值减 1。如果信号量值为 0,则阻塞直到信号量值大于 0。
int sem_trywait(sem_t *sem);尝试将信号量值减 1。如果信号量值为 0,不阻塞,返回错误。
int sem_post(sem_t *sem);将信号量的值加 1。如果有阻塞的线程,唤醒其中一个线程。
int sem_getvalue(sem_t *sem, int *sval);获取信号量的当前值。

4. 示例

(1) 线程间的同步

以下是一个简单的生产者-消费者问题示例,演示如何使用信号量控制线程同步:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>#define BUFFER_SIZE 5int buffer[BUFFER_SIZE];
int count = 0;sem_t empty;  // 表示空位的信号量
sem_t full;   // 表示已占用位的信号量
pthread_mutex_t mutex;  // 保护共享资源的互斥锁void *producer(void *arg) {for (int i = 0; i < 10; i++) {sem_wait(&empty);             // 减少空位pthread_mutex_lock(&mutex);   // 进入临界区buffer[count++] = i;          // 放入数据printf("Produced: %d\n", i);pthread_mutex_unlock(&mutex); // 离开临界区sem_post(&full);              // 增加已占用位sleep(1);}return NULL;
}void *consumer(void *arg) {for (int i = 0; i < 10; i++) {sem_wait(&full);              // 减少已占用位pthread_mutex_lock(&mutex);   // 进入临界区int item = buffer[--count];   // 取出数据printf("Consumed: %d\n", item);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;
}
输出示例
Produced: 0
Consumed: 0
Produced: 1
Produced: 2
Consumed: 1
Consumed: 2
...

(2) 进程间的同步

信号量也可以在进程间共享,但需要设置 sem_initpshared 参数为非 0,并将信号量存储在共享内存中。


5. 注意事项

  1. 线程间 vs 进程间信号量

    • pshared 为 0 时,信号量用于线程间同步。
    • 为非 0 时,需要将信号量置于共享内存区域,用于进程间同步。
  2. 阻塞与非阻塞操作

    • sem_wait 会阻塞直到信号量值大于 0。
    • sem_trywait 不会阻塞,而是立即返回成功或失败。
  3. 信号量的销毁

    • 在不再需要信号量时,必须调用 sem_destroy 释放资源。
  4. 避免死锁

    • 正确管理信号量和互斥锁的顺序,以避免线程或进程死锁。

6. 总结

<semaphore.h> 提供了信号量相关的功能,适用于多线程或多进程场景下的同步问题。通过使用 sem_t 数据类型及相关函数,开发者可以有效地控制对共享资源的访问,确保线程安全。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com