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

sem_init的概念和使用案例

sem_init 是 POSIX 线程库中用于初始化未命名信号量(unnamed semaphore)的函数,常用于多线程或多进程间的同步。以下是其概念和使用案例的详细说明:


概念

  • 函数原型
     #include <semaphore.h>
     int sem_init(sem_t *sem, int pshared, unsigned int value);
    
  • 参数
    • sem:指向信号量对象的指针。
    • pshared:决定信号量的共享范围:
      • 0:信号量在线程间共享(同一进程内)。
      • 0:信号量在进程间共享(需配合共享内存使用)。
    • value:信号量的初始值(通常表示可用资源的数量)。
  • 返回值
    • 成功返回 0,失败返回 -1 并设置 errno

使用案例

场景 1:多线程同步(线程间共享)
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sem;
int shared_resource = 0;

void* thread_func(void* arg) {
    sem_wait(&sem); // 等待信号量
    shared_resource++; // 访问共享资源
    printf("Thread %ld: shared_resource = %d\n", (long)pthread_self(), shared_resource);
    sem_post(&sem); // 释放信号量
    return NULL;
}

int main() {
    pthread_t t1, t2;
    
    // 初始化信号量(线程间共享,初始值为1)
    if (sem_init(&sem, 0, 1) == -1) {
        perror("sem_init failed");
        return 1;
    }

    pthread_create(&t1, NULL, thread_func, NULL);
    pthread_create(&t2, NULL, thread_func, NULL);

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

    sem_destroy(&sem); // 销毁信号量
    return 0;
}
场景 2:多进程同步(进程间共享)

需将信号量放置在共享内存中:

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <semaphore.h>

int main() {
    // 创建共享内存
    int fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);
    ftruncate(fd, sizeof(sem_t));
    sem_t *sem = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    // 初始化信号量(进程间共享,初始值为1)
    if (sem_init(sem, 1, 1) == -1) {
        perror("sem_init failed");
        return 1;
    }

    // 父子进程示例
    if (fork() == 0) {
        sem_wait(sem);
        printf("Child process: Accessing resource\n");
        sem_post(sem);
        _exit(0);
    } else {
        sem_wait(sem);
        printf("Parent process: Accessing resource\n");
        sem_post(sem);
        wait(NULL);
    }

    sem_destroy(sem);    // 销毁信号量
    shm_unlink("/my_shm"); // 清理共享内存
    return 0;
}

注意事项

  1. 未命名 vs 命名信号量

    • sem_init 用于未命名信号量,生命周期由程序控制。
    • 命名信号量(通过 sem_open 创建)可用于无亲缘关系的进程间同步。
  2. 废弃警告

    • 在较新的系统(如 Linux 2.6+),sem_init 已被标记为废弃,建议改用 sem_open + sem_unlink
  3. 资源释放

    • 必须调用 sem_destroy 释放信号量资源,避免内存泄漏。
  4. 编译命令

    gcc program.c -pthread -lrt  # 链接 pthread 和 rt 库(进程间共享需要)
    

通过合理使用 sem_init,可以实现线程或进程间的同步控制(如互斥锁、资源计数等)。


http://www.kler.cn/a/525429.html

相关文章:

  • 最新-CentOS 7 基于1 Panel面板安装 JumpServer 堡垒机
  • 【C语言】main函数解析
  • 使用Python爬虫获取1688商品拍立淘API接口(item_search_img)的实战指南
  • 设计模式-建造者模式、原型模式
  • Linux C++
  • LangGraph系列-1:用LangGraph构建简单聊天机器人
  • ollama的setup.exe和ollama-windows-amd64.zip区别
  • 网易有道开源 “子曰 - o1” 推理模型
  • Python动量策略实战:大幅跑赢市场的底层逻辑
  • 跑腿小程序/智能派单/系统派单/同城配送/校园跑腿/预约取件/用户端+骑手端【全开源】
  • 多线程进阶(一命通关)
  • 抠图神器,全离线使用,支持win和mac
  • github制作静态网页
  • 高精度算法:高精度减法
  • 【C++动态规划 状态压缩】2597. 美丽子集的数目|2033
  • 单细胞-第五节 多样本数据分析,打分R包AUCell
  • 简单聊聊“DeepSeek”
  • 【设计测试用例自动化测试性能测试 实战篇】
  • 2.3.1 基本数据类型
  • 获取snmp oid的小方法1(随手记)
  • 谈谈道教生物学
  • 蛇年新春 利士策与您 共贺吉祥
  • 【go语言】结构体
  • 有一对兔子,从出生后第三个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
  • buu-pwn1_sctf_2016-好久不见29
  • 阅读:在方寸之间重构人类文明的精神版图