Linux 信号量的使用

信号量的作用是给共享内存加锁

信号量只允许进程进行等待和发送信号操作

通用信号量应用场景较少,一般使用二元信号量

信号量和互斥锁的原理是类似的

引用头文件

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>

相关函数

1.初始化信号量
int sem_init(sem_t *sem, int pshared, unsigned int value);
  • sem:需要初始化的信号量。
  • pshared:传入0值表示线程间共享,传入非零值表示进程间共享。
  • value:信号量的初始值(计数器的初始值)。

返回值说明:

  • 初始化信号量成功返回0,失败返回-1。
2.销毁信号量
int sem_destroy(sem_t *sem);

参数说明:

  • sem:需要销毁的信号量。

返回值说明:

  • 销毁信号量成功返回0,失败返回-1。
3.等待信号量(申请信号量)
int sem_wait(sem_t *sem);

参数说明:

  • sem:需要等待的信号量。

返回值说明:

  • 等待信号量成功返回0,信号量的值减一。
  • 等待信号量失败返回-1,信号量的值保持不变。
4.发布信号量(释放信号量)
int sem_post(sem_t *sem);

参数说明

  • sem:需要发布的信号量。

返回值说明:

  • 发布信号量成功返回0,信号量的值加一。
  • 发布信号量失败返回-1,信号量的值保持不变。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <unistd.h>
#include <semaphore.h>

int main()
{
    int shmky = ftok("./test1.cpp",'a');                                 //通过同一个文件生成相同的key,用于读取同一个内存
    if(shmky<0){
        perror("ftok");
        return -2;
    }


    int shmid = shmget(shmky,128,0755|IPC_CREAT);                      //1.创建共享内存空间
    if(shmid<0){
        perror("shmget");
        exit(1);
    }
    printf("shmget success %d\n",shmid);                                //创建的共享内存可用 ipcrm -m id删除
    system("ipcs -m");                                                  //调用内核,显示当前系统的共享内存

    sem_t sem;
    int sem_id = sem_init(&sem, 1, 1);

    int pid = fork();//创建4个进程同时操作同一个共享内存
    if(pid ==0)
    {
        int pid2 = fork();
        if(pid2 ==0)
        {
            int* i = (int*)shmat(shmid,NULL,0);                                 //将char类型数据关联到共享内存     
            sem_wait(&sem); 
            (*i)=0; 
            sem_post(&sem);                             
            for(int x = 0;x<100;x++)
            {
                sem_wait(&sem); 
                printf("process1    i=%d\n",*i);
                (*i)++;
                sem_post(&sem);  
            }
            shmdt(i);   
        } else{
            int* i = (int*)shmat(shmid,NULL,0);                                 //将char类型数据关联到共享内存                                    
            for(int x = 0;x<100;x++)
            {
                sem_wait(&sem); 
                printf("process2    i=%d\n",*i);
                (*i)++;
                sem_post(&sem);  
            }
            shmdt(i);   
        }
    }else{
        int pid3 = fork();
        if(pid3 ==0)
        {
            int* i = (int*)shmat(shmid,NULL,0);                                 //将char类型数据关联到共享内存                                    
            for(int x = 0;x<100;x++)
            {
                sem_wait(&sem); 
                printf("process3    i=%d\n",*i);
                (*i)++;
                sem_post(&sem);  
            }
            shmdt(i);   
        } else{
            int* i = (int*)shmat(shmid,NULL,0);                                 //将char类型数据关联到共享内存                                    
            for(int x = 0;x<100;x++)
            {
                sem_wait(&sem); 
                printf("process4    i=%d\n",*i);
                (*i)++;
                sem_post(&sem);  
            }
            shmdt(i);   
            sleep(5);
            sem_destroy(&sem);
            shmctl(shmid,IPC_RMID,NULL);
        }
    }   
}

要验证代码的话,将某个进程中的sem_post注释,即可发现程序会卡在该进程

相关推荐

  1. Linux 信号使用

    2024-03-14 12:40:02       41 阅读
  2. Linux信号(简易版)

    2024-03-14 12:40:02       44 阅读
  3. linux段异常信号

    2024-03-14 12:40:02       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-14 12:40:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-14 12:40:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-14 12:40:02       87 阅读
  4. Python语言-面向对象

    2024-03-14 12:40:02       96 阅读

热门阅读

  1. Mysql将datetime数据转为Data/Char

    2024-03-14 12:40:02       34 阅读
  2. linux内核网络揭秘《二》“每日读书”

    2024-03-14 12:40:02       45 阅读
  3. 高防服务器能够抵御哪些攻击?

    2024-03-14 12:40:02       44 阅读
  4. C语言自学笔记10----C语言数组

    2024-03-14 12:40:02       37 阅读
  5. SpringBoo和vue项目blob传参未生效

    2024-03-14 12:40:02       42 阅读
  6. 蚓链助新零售企业快速实现数字化转型

    2024-03-14 12:40:02       44 阅读
  7. 用python实现人生重开模拟器游戏

    2024-03-14 12:40:02       45 阅读
  8. (自用)Spring常用配置

    2024-03-14 12:40:02       39 阅读
  9. sheel和setuptools两个包的作用

    2024-03-14 12:40:02       35 阅读
  10. 【Scala】一、Scala 语法基础

    2024-03-14 12:40:02       44 阅读
  11. JVM是如何解决跨代引用的?

    2024-03-14 12:40:02       34 阅读