【Linux学习】System V (2) 代码

下面是有关进程通信中 System V 代码的相关介绍,希望对你有所帮助!

小海编程心语录-CSDN博客

目录

1. 消息队列 msg 

2. 共享内存 shm 

3. 信号量  sem


1. 消息队列 msg 

示例代码 

//发送端 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
struct message      //带有标识的结构体
{
    long mtype;     //消息类型(固定)

    char mtext[100];    //消息正文(可变)

};

int main()
{
    // 以当前目录和序号1为系数产生一个对应的键值
    // 创建(若存在则报错)key对应的MSG对象
    int msgid;
    msgid = msgget(ftok(".", 1), IPC_CREAT|0666); 

    struct message msg;             //结构体全局变量
    bzero(&msg, sizeof(msg));       //先清空发送的数据

    msg.mtype = 1;                  //消息类型

    fgets(msg.mtext, 100 ,stdin);   //从键盘键入消息本体

    msgsnd(msgid, &msg, strlen(msg.mtext) ,0); //发送消息
    
}
//接收端
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>

struct message
{
    long mtype;

    char mtext[100];

};

int main()
{
    // 以当前目录和序号1为系数产生一个对应的键值
    // 创建(若存在则报错)key对应的MSG对象
    int msgid;
    msgid = msgget(ftok(".", 1), IPC_CREAT|0666);

    struct message msgbuf;
    bzero(&msgbuf, sizeof(msgbuf));     //先清空发送的数据

    printf("wait...\n");            //等待接收提示

    int msglong = msgrcv(msgid, &msgbuf, sizeof(msgbuf)-sizeof(long) ,1,0);     //接收消息
    if(msglong<0)                          //没有接收到
    {
        perror("msgrcv()");
    }
    else                                    //接收到了
        printf("%s\n", msgbuf.mtext);       //打印文本信息
    msgctl(msgid, IPC_RMID, NULL);          //删除MSG对象,释放内存

    return 0;
    
}

打开两个终端,编译后执行文件 ,可以发现发送端等待输入发送内容,接收端等待接收消息内容。

可以发现在发送端输入“111”后,接收端接收到“111”,只能执行一次就退出。

 


2. 共享内存 shm 

示例代码 

//发送端 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{

    // 以当前目录和序号1为系数产生一个对应的键值
    // 创建(若存在则报错)key对应的SHM对象
    char msg[100];
    
    int shmid;
    shmid = shmget(ftok(".", 1),1024, IPC_CREAT|0600);
    if(shmid<0)
    {
        perror("failed");
        exit(-1);
    }
    printf("shm id is : %d\n", shmid);

    //映射
    char * shmc = (char *)shmat(shmid, NULL, 0);
    printf("shm映射 success\n");
    
    //从键盘键入消息本体
    fgets(msg, 99, stdin);
    //memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1。
    memcpy(shmc, msg, sizeof(msg));

    //解除映射
    shmdt(shmc);
    printf("shm解除映射 success");
  
    //删除SHM对象,释放内存
    shmctl(shmid, IPC_RMID, NULL);

    return 0;

}
//接收端 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    // 以当前目录和序号1为系数产生一个对应的键值
    // 创建(若存在则报错)key对应的SHM对象
    int shmid;
    shmid = shmget(ftok(".", 1),1024, IPC_CREAT|0600);
    if(shmid<0)
    {
        perror("failed");
        exit(-1);
    }
    printf("shm id is : %d\n", shmid);

    //映射
    char * shms = (char *)shmat(shmid, NULL, 0);
    printf("shm映射 success\n");

    while(strlen(shms)==0)
    {
        sleep(1);
        printf("内容是:%s\n", shms);        
    }
    
    //解除映射
    shmdt(shms);
    printf("shm解除映射 success");

    //删除SHM对象,释放内存
    shmctl(shmid, IPC_RMID, NULL);

    return 0;

}

从下方图片可看出

发送端第一行是打印的SHM对象ID,第二行是映射成功提示语,第三行是输入的内容“111”,第四行是解除映射成功提示语。

接收端第一行是打印的SHM对象ID,第二行是映射成功提示语,第三行往后等待接收输入的内容,接收到的内容是“111”。最后一行是解除映射成功提示语。

 


3. 信号量  sem

示例代码 

//发送端 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>

int main()
{
    //1.获取共享内存key值
    key_t key = ftok(".", 10);
    //2.获取共享内存ID号
    int shmid;
    shmid = shmget(key,1024, IPC_CREAT|0600);
    if(shmid<0)
    {
        perror("failed");
        exit(-1);
    }
    printf("shm id is : %d\n", shmid);
    //3.映射
    char * shmc = (char *)shmat(shmid, NULL, 0);

    //4.获取信号量key值
    key_t key1 = ftok(".", 20);

    //5.获取信号量ID
    int semid;
    semid = semget(key1, 2,IPC_CREAT|0666);

    //6.初始化信号量的值
    semctl(semid, 0, SETVAL, 1); //time
    semctl(semid, 1, SETVAL, 0); //space
    //time[0] : 1
    struct sembuf semtime;
    semtime.sem_num = 0;    //time 
    semtime.sem_op = -1;    //P操作
    semtime.sem_flg = 0;    //普通属性
    //sapce[1] : 0
    struct sembuf semspace;
    semspace.sem_num = 1;    //space
    semspace.sem_op = 1;    //V操作
    semspace.sem_flg = 0;    //普通属性

    while(1)
    {
        semop(semid, &semtime, 1); //p操作 :-1后判断是否执行
        scanf("%s", shmc);
        semop(semid, &semspace, 1);

    }

    //解除映射
    shmdt(shmc);

    shmctl(shmid, IPC_RMID, NULL);

    semctl(semid, 0, IPC_RMID);
    return 0;

}
//接收端 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>

int main()
{
    //1.获取共享内存key值
    key_t key = ftok(".", 10);
    //2.获取共享内存ID号
    int shmid;
    shmid = shmget(key,1024, IPC_CREAT|0600);
    if(shmid<0)
    {
        perror("failed");
        exit(-1);
    }
    printf("shm id is : %d\n", shmid);
    //3.映射
    char * shmc = (char *)shmat(shmid, NULL, 0);

    //4.获取信号量key值
    key_t key1 = ftok(".", 20);

    //5.获取信号量ID
    int semid;
    semid = semget(key1, 2,IPC_CREAT|0666);

    //6.初始化信号量的值
    semctl(semid, 0, SETVAL, 1); //time
    semctl(semid, 1, SETVAL, 0); //space
    struct sembuf semtime;
    semtime.sem_num = 0;    //time 
    semtime.sem_op = 1;    //V操作
    semtime.sem_flg = 0;    //普通属性
    struct sembuf semspace;
    semspace.sem_num = 1;    //space
    semspace.sem_op = -1;    //P操作
    semspace.sem_flg = 0;    //普通属性

    while(1)
    {
        semop(semid, &semspace, 1);
        printf("收到的数据是:%s\n", shmc);
        sleep(2);

        semop(semid, &semtime, 1);
        
    }

    return 0;

}

接收端和发送端都打印了SHM对象ID,等待发送端发送内容,接收端也在等待。

当发送端输入内容后,接收端接收到数据,并且可以持续发送接收。


上面是有关进程通信中 System V IPC 的相关介绍

如果喜欢请不吝给予三连支持!

小海编程心语录-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值