目录

前言

一、system V IPC对象图解

1.流程图解:

​编辑

2.查看linux内核中的ipc对象:

 二、消息队列

1.消息队列的原理

2.消息队列相关的API

2.1 获取或创建消息队列(msgget)

 实例代码如下:

2.2 发送消息到消息队列中

 实例代码如下:

2.3 从消息队列中获取消息  

实例代码如下: 

 2.4 消息队列相关的命令

 2.5 管理消息队列

 实例代码如下:

三、共享内存

1.概念

2.原理图解

3.相关的api函数

3.1 创建共享内存对象

 实例代码如下:

3.2 映射共享内存  

 3.3 取消映射

 实例代码reader.c如下:

 实例代码writer.c如下:

实例代码shm.h 如下:

 3.4 管理共享内存

实例代码如下: 

四、信号灯 (信号量)

1.概念

2.信号灯相关的api函数

2.1 创建或获取信号灯对象

实例代码如下:

2.2 实现P操作和V操作  

实例代码如下:

2.3 管理信号灯  

实例代码如下: 

总结


前言

System V IPC(Inter-Process Communication)对象是一种用于在不同进程之间进行通信的机制。它包括三种类型的对象:消息队列(Message Queue)、信号量(Semaphore)和共享内存(Shared Memory)。


一、system V IPC对象图解

1.流程图解:

C/C++ 进程间通信system V IPC对象超详细讲解(系统性学习day9)-LMLPHP

2.查看linux内核中的ipc对象:

C/C++ 进程间通信system V IPC对象超详细讲解(系统性学习day9)-LMLPHP

 二、消息队列

1.消息队列的原理

C/C++ 进程间通信system V IPC对象超详细讲解(系统性学习day9)-LMLPHP

 

2.消息队列相关的API

2.1 获取或创建消息队列(msgget)

 实例代码如下:
int main(void)
{
    key_t key;
    int msg_id;

    //获取key值
    key = ftok("./",0xa);
    if(key < 0){
        perror("ftok");
        exit(1);
    }
    //创建或获取消息对象
    msg_id = msgget(key,IPC_CREAT|0666);
    if(msg_id < 0){
        perror("msgget");
        exit(1);
    }
    return 0;
}

2.2 发送消息到消息队列中

 实例代码如下:
int main(void)
{
    key_t key;
    int msg_id;

    //获取key值
    key = ftok("./",0xa);
    if(key < 0){
        perror("ftok");
        exit(1);
    }
    //创建或获取消息对象
    msg_id = msgget(key,IPC_CREAT|0666);
    if(msg_id < 0){
        perror("msgget");
        exit(1);
    }

//向消息队列中发送消息
    while(1){
        bzero(&buf,sizeof(buf));
        printf("请输入消息的类型:");
        scanf("%ld",&buf.mtype);
        printf("请输入消息:");
        while(getchar() != '\n');   //清空输入缓冲区
        fgets(buf.mtext,sizeof(buf.mtext),stdin);
        buf.mtext[strlen(buf.mtext)-1] = '\0';
        if(msgsnd(msg_id,&buf,strlen(buf.mtext),0) < 0){
            perror("msgsnd");
            exit(1);
        }
    }

    return 0;
}

2.3 从消息队列中获取消息  

实例代码如下: 
int main(void)
{
    key_t key;
    int msg_id;

    //获取key值
    key = ftok("./",0xa);
    if(key < 0){
        perror("ftok");
        exit(1);
    }
    //创建或获取消息对象
    msg_id = msgget(key,IPC_CREAT|0666);
    if(msg_id < 0){
        perror("msgget");
        exit(1);
    }

//从消息队列中获取消息
    while(1){
        bzero(&buf,sizeof(buf));
        printf("请输入消息的类型:");
        scanf("%ld",&buf.mtype);
        if(msgrcv(msg_id,&buf,sizeof(buf.mtext),buf.mtype,0) < 0){
            perror("msgsnd");
            exit(1);
        }
        printf("msg:%s\n",buf.mtext);
    }

    return 0;
}

 2.4 消息队列相关的命令

 2.5 管理消息队列

 实例代码如下:
int main(int argc,char **argv)
{
    int msg_id;

    msg_id = atoi(argv[1]);

    if(msgctl(msg_id,IPC_RMID,NULL) < 0){
        perror("msgget");
        exit(1);
    }
    return 0;
}

三、共享内存

1.概念

2.原理图解

 C/C++ 进程间通信system V IPC对象超详细讲解(系统性学习day9)-LMLPHP

 

3.相关的api函数

3.1 创建共享内存对象

 实例代码如下:
int main(void)
{
    key_t key;
    int shm_id;

    //获取key值
    key = ftok("./",0xa);
    if(key < 0){
        perror("ftok");
        exit(1);
    }
    //创建或获取共享内存对象
    shm_id = shmget(key,SHM_SIZE, IPC_CREAT|0666);
    if(shm_id < 0){
        perror("shmget");
        exit(1);
    }
    return 0;
}

3.2 映射共享内存  

 3.3 取消映射

 实例代码reader.c如下:
#include "shm.h"

int main(void)
{
    key_t key;
    int shm_id;
    char *buf;

    //获取key值
    key = ftok("./",0xa);
    if(key < 0){
	perror("ftok");
	exit(1);
    }
    //创建或获取共享内存对象
    shm_id = shmget(key,SHM_SIZE, IPC_CREAT|0666);
    if(shm_id < 0){
	perror("shmget");
	exit(1);
    }

    //将共享内存映射到进程的虚拟空间中
    buf = (char*)shmat(shm_id,NULL,0);
    if(buf < 0){
	perror("shmat");
	exit(1);
    }


    //打印共享内存中的数据
    while(1){
	printf("%s",buf);
	sleep(1);
    }

    //解除映射
    if(shmdt(buf) < 0){
	perror("shmdt");
	exit(1);
    }
    return 0;
}
 实例代码writer.c如下:
#include "shm.h"

int main(void)
{
    key_t key;
    int shm_id;
    char *buf;

    //获取key值
    key = ftok("./",0xa);
    if(key < 0){
	perror("ftok");
	exit(1);
    }
    //创建或获取共享内存对象
    shm_id = shmget(key,SHM_SIZE, IPC_CREAT|0666);
    if(shm_id < 0){
	perror("shmget");
	exit(1);
    }

    //将共享内存映射到进程的虚拟空间中
    buf = (char*)shmat(shm_id,NULL,0);
    if(buf < 0){
	perror("shmat");
	exit(1);
    }


    //向共享内存写数据
    while(1){
	printf("请输入字符串:");
	fgets(buf,SHM_SIZE,stdin);
    }

    //解除映射
    if(shmdt(buf) < 0){
	perror("shmdt");
	exit(1);
    }
    return 0;
}
实例代码shm.h 如下:
#ifndef __SHM_H__
#define __SHM_H__

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

#define SHM_SIZE  1024

#endif

 3.4 管理共享内存

实例代码如下: 
int main(int argc,char **argv)
{
    int shm_id;

    shm_id = atoi(argv[1]);

    if(shmctl(shm_id,IPC_RMID,NULL) < 0){
        perror("shmget");
        exit(1);
    }
    return 0;
}

四、信号灯 (信号量)

1.概念

2.信号灯相关的api函数

2.1 创建或获取信号灯对象

实例代码如下:
int main(void)
{
    key_t key;
    int sem_id;

    //获取key值
    key = ftok("./",0xa);
    if(key < 0){
        perror("ftok");
        exit(1);
    }
    //创建或获取共享内存对象
    sem_id = semget(key,1, IPC_CREAT|0666);
    if(sem_id < 0){
        perror("semget");
        exit(1);
    }
    return 0;
}

2.2 实现P操作和V操作  

实例代码如下:
//1》实现P操作
	void sem_p(int sem_id,int index)
    {
        struct sembuf buf = {index,-1,0};

        if(semop(sem_id,&buf,1) < 0){
            perror("semop");
            exit(1);
        }
    }
//2》实现v操作
    void sem_v(int sem_id,int index)
    {
        struct sembuf buf = {index,1,0};

        if(semop(sem_id,&buf,1) < 0){
            perror("semop");
            exit(1);
        }
    }

2.3 管理信号灯  

实例代码如下: 
//初始化指定的信号灯
void sem_init(int sem_id,int semnum,int value)
{
    union semun su;
    su.val = value;
    if(semctl(sem_id,semnum,SETVAL,su) < 0){
        perror("semctl");
        exit(1);
    }
}
//初始化所有信号灯
void sem_init_all(int sem_id,unsigned short vals[])
{
    union semun su;
    su.array = vals;
    if(semctl(sem_id,0,SETALL,su) < 0){
        perror("semctl");
        exit(1);
    }
}


总结

        本篇文章针对进程间通信system V IPC对象进行详细讲解,希望能够帮到大家!

        以后还会给大家展现更多关于嵌入式和C语言的其他重要的基础知识,感谢大家支持懒大王!

       希望这篇博客能给各位朋友们带来帮助,最后懒大王请来过的朋友们留下你们宝贵的三连以及关注,感谢你们!

10-09 15:47