Linux从入门到开发实战(C/C++)Day06-IPC

点击前往Day07-信号

IPC:Inter Process Communicate
         中间     进程       通信
    根据操作系统(os)不同会有不同的两个版本:ANSI版本 和 POSIX版本

    共享内存:shm share memory
        多个进程都可以访问os之上的一块内存段

    消息队列:msg message queue
        在主机上指定一个或多个队列
        不同进程可以发送消息到队列中,或者从队列中获取消息(按照对应类型拿)

    旗语(信号量):sem semaphore
        多个进程不可能同时访问一块区域
        用一个整数 进程都能对它做加减操作
        加 随便加
        减 最小减到0(阻塞)

    以上三种都要使用到key
        key的本质是一个int类型的整数,保证IPC的唯一性
        key都是通过fd创建
    用来查看当前主机的IPC的命令:ipcs

    共享内存编程模型:
        1.创建key        ftok
        #include <sys/types.h>
        #include <sys/ipc.h>
        key_t ftok(const char *pathname, int proj_id);
            proj_id 非零整数 8个bit位 1-255

        2.创建共享内存    shmget
        #include <sys/ipc.h>
        #include <sys/shm.h>
        int shmget(key_t key, size_t size, int shmflg);

        3.挂载共享内存    shmat
        #include <sys/types.h>
        #include <sys/shm.h>
        void *shmat(int shmid, const void *shmaddr, int shmflg);
        int shmdt(const void *shmaddr);

        4.使用
        5.卸载共享内存    shmdt
        6.删除共享内存    shmctl
        #include <sys/ipc.h>
        #include <sys/shm.h>
        int shmctl(int shmid, int cmd, struct shmid_ds *buf);

        shmA                                                    shmB
    1.创建key        ftok                            1.创建key        ftok
    2.创建共享内存    shmget                 2.获取共享内存
    3.挂载共享内存    shmat                   3.挂载
    4.使用                                               4.使用
    5.卸载共享内存    shmdt                   5.卸载
    6.删除共享内存    shmctl

    信号(因为需要所以这里简单讲点):
        信号是个整数,os提供了64个信号(主要是前32个)
        特殊行为用对应的信号来表示
            终端强制结束一个进程 SIGINT 2
            杀进程    SIGKILL    9
            ...
        本身信号的处理是固定的,不同信号有不同的处理方式
        我们可以使用signal函数,自己注册信号的处理

     #include <signal.h>
     typedef void (*sighandler_t)(int);
     sighandler_t signal(int signum, sighandler_t handler);
    
    消息队列编程模型:
        1.创建key
        2.创建消息队列
            msgget
        #include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/msg.h>
        int msgget(key_t key, int msgflg);

        3.收发消息
                msgrcv 接收
                msgsnd 发送
        #include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/msg.h>
        int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
        ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
        注意:接收消息会按照类型接收(msgtyp)

        4.删除消息队列        msgctl
        #include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/msg.h>
        int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    
    旗语(信号量)编程模型:
        1.创建key        ftok
        2.创建信号量    semget
        #include <sys/types.h>
           #include <sys/ipc.h>
           #include <sys/sem.h>
           int semget(key_t key, int nsems, int semflg);
        
        3.初始化信号量    semctl
        #include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/sem.h>
        int semctl(int semid, int semnum, int cmd, ...);

        4.使用信号量    semop
        #include <sys/types.h>
        #include <sys/ipc.h>
        #include <sys/sem.h>
        int semop(int semid, struct sembuf *sops, size_t nsops);

        5.删除信号量    semctl

相关示例:

#include <stdio.h>
#include <unistd.h> //linux操作系统标准头文件
#include <string.h> //memcpy
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h> //umask
#include <time.h>
#include <sys/time.h>
#include <dirent.h> //遍历目录
#include <fcntl.h>	//文件映射虚拟内存
#include <sys/mman.h>
#include <wait.h>
#include <signal.h> //SIGCHLD
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <poll.h>
#include <sys/epoll.h>
#include <pthread.h>
#include <bits/pthreadtypes.h>
#include <aio.h>
#include <netdb.h>
#include <netinet/ip_icmp.h>

// 信号
void hand(int s)
{
	printf("收到信号:%d\n", s);
}
void _signal()
{
	signal(2, hand);
	int n = 0;
	while (1)
	{
		printf("%d\n", n++);
		sleep(1);
	}
}

// shmctl删除共享内存
void _shmctl()
{
	// 1.创建key		ftok
	key_t key = ftok("./", 'm');
	if (-1 == key)
	{
		printf("创建key失败%m\n");
		return -1;
	}
	printf("创建key成功\n");
	// 2.创建共享内存	shmget
	int shmid = shmget(key, 4096, IPC_CREAT | 0666);
	if (-1 == shmid)
	{
		printf("创建共享内存失败%m\n");
		return -1;
	}
	printf("创建共享内存成功\n");
#if 0
	//3.删除共享内存
	int r = shmctl(shmid,IPC_RMID,NULL);
	if (-1 == r)
    {
        printf("删除共享内存失败%m\n");
        return -1;
    }
    printf("删除共享内存成功\n");
#else
	// 获取共享内存状态
	struct shmid_ds ds = {0};
	int r = shmctl(shmid, IPC_STAT, &ds);
	if (-1 == r)
	{
		printf("获取共享内存失败%m\n");
		return -1;
	}
	printf("获取共享内存成功\n");
	printf("挂载数:%d\n", ds.shm_nattch);
	printf("创建进程id:%d\n", ds.shm_cpid);
	printf("大小:%d\n", ds.shm_segsz);
#endif
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值