首页 > 其他分享 >利用信息量集实现互斥访问

利用信息量集实现互斥访问

时间:2024-05-28 19:14:00浏览次数:21  
标签:IPC 访问 信息量 semid 互斥 int sem include id

进程A

用来生成信号集,并将其初值设为1(运行顺序为进程A->B->C)

/*
 * @Author: Eon [email protected]
 * @Date: 2024-05-08 17:20:41
 * @LastEditors: Eon [email protected]
 * @LastEditTime: 2024-05-28 18:47:38
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <error.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
union semun
{
    int val;               /* value for SETVAL */
    struct semid_ds *buf;  /* buffer for IPC_STAT, IPC_SET */
    unsigned short *array; /* array for GETALL, SETALL */
    struct seminfo *__buf; /* buffer for IPC_INFO */
};

int main()
{
    union semun arg;

    // 创建信号量集
    int sem_id = semget(ftok("./mysem", 20), 1, 0664 | IPC_CREAT | IPC_EXCL);
    if (sem_id == -1)
    {
        fprintf(stderr, "semid open is false,errno:%d,%s\n", errno, strerror(errno));
        sem_id = semget(ftok("./mysem", 20), 1, 0664);
    }
	//设置信号量集的初始值为1
    arg.val = 1;
    semctl(sem_id, 0, SETVAL, arg);

    //int ret = semctl(sem_id, 0, GETVAL, arg);
    //printf("sem[0]=%d", ret);
    // 将共享空间内初值设为0
    int shm_id = shmget(ftok("./myshm", 21), 4, 0666 | IPC_CREAT);
    int *a = (int *)shmat(shm_id, NULL, 0);
    *a = 1;
    shmdt(a);

    //printf("sem_id=%d\n", sem_id);

    //printf("shm_id=%d\n", shm_id);

    while (1)
    {
        sleep(1);
    }

    return 0;
}

进程B

用来对共享内存内的int值进行修改,每秒+1

/*
 * @Author: Eon [email protected]
 * @Date: 2024-05-08 17:20:41
 * @LastEditors: Eon [email protected]
 * @LastEditTime: 2024-05-28 18:29:25
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <error.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
// struct sembuf
// {
//     unsigned short sem_num;
//     short sem_op;
//     short sem_flg;
// };
/***对信号量数组semnum编号的信号量做P操作(申请)***/
int P(int semid, int semnum)
{
    struct sembuf sops = {semnum, -1, SEM_UNDO};

    return (semop(semid, &sops, 1));
}
/***对信号量数组semnum编号的信号量做V操作(释放)***/
int V(int semid, int semnum)
{
    struct sembuf sops = {semnum, +1, 0};

    return (semop(semid, &sops, 1));
}

int main()
{
    // b端修改共享内存内的值
    int sem_id = semget(ftok("./mysem", 20), 1, 0664 | IPC_CREAT | IPC_EXCL);
    if (sem_id == -1)
    {
        fprintf(stderr, "semid open is false,errno:%d,%s\n", errno, strerror(errno));
        sem_id = semget(ftok("./mysem", 20), 1, 0664);
    }
	int shm_id = shmget(ftok("./myshm", 21), 4, 0666 | IPC_CREAT);
    //printf("sem_id=%d\n", sem_id);
	//printf("shm_id=%d\n", shm_id);
    while (1)
    {
        P(sem_id, 0);
        int *a = (int *)shmat(shm_id, NULL, 0);
        int temp = (*a) + 1;
        //printf("输入为%d\n", temp);
        *a = (*a) + 1;
        shmdt(a);
        sleep(1);
        V(sem_id, 0);
    }

    return 0;
}

进程C

用来读取共享内存内的数据并将其在命令行终端输出

/*
 * @Author: Eon [email protected]
 * @Date: 2024-05-08 17:20:41
 * @LastEditors: Eon [email protected]
 * @LastEditTime: 2024-05-28 18:49:55
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <error.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

// struct sembuf
// {
//     unsigned short sem_num;
//     short sem_op;
//     short sem_flg;
// };
/***对信号量数组semnum编号的信号量做P操作(申请)***/
int P(int semid, int semnum)
{
    struct sembuf sops = {semnum, -1, SEM_UNDO};

    return (semop(semid, &sops, 1));
}
/***对信号量数组semnum编号的信号量做V操作(释放)***/
int V(int semid, int semnum)
{
    struct sembuf sops = {semnum, +1, 0};

    return (semop(semid, &sops, 1));
}

int main()
{
    // C端输出共享内存内的值
    int sem_id = semget(ftok("./mysem", 20), 1, 0664 | IPC_CREAT | IPC_EXCL);
    if (sem_id == -1)
    {
        fprintf(stderr, "semid open is false,errno:%d,%s\n", errno, strerror(errno));
        sem_id = semget(ftok("./mysem", 20), 1, 0664);
    }
	int shm_id = shmget(ftok("./myshm", 21), 4, 0666 | IPC_CREAT);
    //printf("sem_id=%d\n", sem_id);
    //printf("shm_id=%d\n", shm_id);
    while (1)
    {
        P(sem_id, 0);
        int *a = (int *)shmat(shm_id, NULL, 0);
        //printf("共享内存内的值为:%d\n", a[0]);
        shmdt(a);
        sleep(1);
        V(sem_id, 0);
    }

    return 0;
}

标签:IPC,访问,信息量,semid,互斥,int,sem,include,id
From: https://www.cnblogs.com/eon4051/p/18218647

相关文章

  • 进程间同步(互斥锁)
    【一】什么是互斥锁互斥锁是一种用于多线程编程中控制对共享资源访问的机制限制当前时间段只能由当前进程使用,当前进程使用完成后才能其他进程继续使用基本原理是在对共享资源进行访问前加锁,使得其他线程无法访问该资源,当访问完成后再解锁,使得其他线程可以进行访问【......
  • 解决 IIS Express 启动错误:“拒绝访问”问题
    报错StartingIISExpress...stderr:FailedtoregisterURL"http://localhost:8378/"forsite"app-3344e220-8b03-465c-8df1-3c41981352a1"application"/".Errordescription:拒绝访问。(0x80070005)Unabletostartiisexpress.拒绝......
  • Nginx(openresty) 通过lua结合Web前端 实现图片,文件,视频等静态资源 访问权限验证,进行
    1本文系统环境:安装openresty(nginx),可参考:test@ubuntuserver:~$cat/etc/os-releasePRETTY_NAME="Ubuntu24.04LTS"NAME="Ubuntu"VERSION_ID="24.04"VERSION="24.04LTS(NobleNumbat)"VERSION_CODENAME=nobleID=ubuntuID_LIK......
  • 如何在本地修改Hosts文件设置域名访问?
    网站在未上线的时候,我们一般会在本地搭建Web环境并安装WordPress来设计页面、测试插件、数据备份、网站搬家。为了能够在本地通过域名访问网站,就需要在修改hosts文件来绑定域名,方法如下:windows系统修改hosts文件步骤1:打开hosts文件,路径如下所示;找到hosts文件,选择使用记事本打开......
  • Linux网站访问控制
    环境:操作系统:centos7(linux)试验系统:win7(client)目的:实现在客户机win7访问网站www.jd.com访问到的是centos的虚拟网站GW开启路由转发以及网络地址转换模式GW开启路由转发grep-v"#"/etc/sysctl.confGW开启网络地址转换模式touchstrat.sh创建strat.sh文件......
  • IP地址证如何实现HTTPS访问?(内网IP、公网IP)
    不能提供域名只能提供IP地址也可以通过部署特定的SSL证书来实现HTTPS访问,这一特定的SSL证书就是IP地址证书。市面上常见的SSL证书多为以域名申请的,以IP地址来申请的SSL证书相对较少见。下面是IP地址证书的申请方法和流程:1选择证书品牌选择能支持公网和内网IP申请SSL证......
  • linux使用ipset禁止国外IP访问
    一、安装ipsetyuminstallipset-y二、禁止firewalldsystemctlstopfirewalldsystemctldisablefirewalld三、设置iptables默认允许规则iptables-PINPUTACCEPT四、清空其他规则[root@hlcc~]#iptables-F五、查看规则[root@hlcc~]#iptables-LChain......
  • 使用阿里云oss,同一个域名前端实现通过路径区分来访问多个不同的项目
     前端存放在阿里云oss上,域名cname解析到阿里云cdn,cdn指向阿里云oss存储 oss中存放的相对目录是这样的:a项目代码目录/a项目静态文文件a项目代码目录/a项目首页文件index.htmla项目代码目录/b项目代码目录bdira项目代码目录/b项目代码目录bdir/b项目代码静态文件a项目......
  • 推荐丨网站https访问也能免费实现了
    2022年Verizon数据泄露调查报告指出,当年75%的社会工程攻击涉及网络钓鱼,仅2022年一年就有超过33万个账户被网络钓鱼,网络钓鱼占整体社会工程攻击的41%。但是也不能将所有责任归咎于运维人员,因为薄弱的安全意识建设及宣教是大部分漏洞利用的原因。在进行网络信息交互的......
  • SqlSugar:基于SQLSugar框架在 .Net环境中搭建PostgreSQL数据库访问、操作的框架,C#连接
    SqlSugar 是一款老牌.NET开源ORM框架,由果糖大数据科技团队维护和更新,开箱即用最易上手的ORM 优点:【生态丰富】【高性能】【超简单】【功能全面】【多库兼容】【适合产品】 【SqlSugar视频教程】 支持:.netframework .netcore3.1 .ne5.net6.net7.net8.n......