Linux-IPC

IPC:Intern Process Communication

           内核进程通信

(1)共享内存:内核会维护主机上的一块内存段   多个进程可以访问内存段。

(2)消息队列:在主机上 指定一个或多个队列,多个进程可以访问。

  (3)   旗语(信号量):希望多个进程 错开时间访问同一块区域。

     这3个都需要key     通过fd来创建key    文件具备唯一性  ftok

一 共享内存:shm   share memory

1.创建key

2.创建共享内存   shmget

3.挂载共享内存   shmat

4.御卸共享内存    shmdt

5.删除共享内存    shmctl

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
int* p = NULL;
void hand(int n)
{
	if(2==n)
	{
		//卸载
		shmdt(p);
		exit(0);
	}

}
int main()
{
	signal(2,hand);
	//1创建key
	key_t key = ftok(".",'m');
	if(-1 == key) printf("ftok error:%m\n"),exit(-1);
	printf("ftok %m\n");

	//2创建共享内存
	int shmid = shmget(key,4096,IPC_CREAT);
	if(-1 == shmid)  printf("shmid error:%m\n"),exit(-1);
	printf("shmid %m\n");
	//3挂载共享内存
	p = (int*)shmat(shmid,NULL,0);
	if(NULL == p) printf("p error:%m\n"),exit(-1);
	printf("p %m\n");
	//4使用
	while(1)
	{
		printf("%d\n",*p);
		sleep(1);
	}
	return 0;

}

用来查看主机上IPC的命令:ipc

ipcs   查看      -m  shm     -q    msg      -s   sem

ipcrm  删除     -m  shm     -q    msg      -s   sem

二 消息队列   smg

1.创建key

2.创建消息队列   msgget

3.收发消息    msgrcv    msgsnd

4.删除消息队列   msgctl

函数原型:

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

 int msgget(key_t key, int msgflg);

 #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);
 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <string.h>
enum myType{TYPEA,TYPEB,TYPEC};

struct msgbuf
{
	long mtype;
	char mtext[20];
};

int main()
{
	struct msgbuf msg;
	msg.mtype = TYPEA;

	//1.创建key
	key_t key = ftok(".",'q');
	if(-1 == key) printf("ftok error:%m\n"),exit(-1);
	printf("ftok %m\n");

	//2.创建消息队列
	int msgid = msgget(key,IPC_CREAT|0666);

	//3.接收
	int r;
	while(1){
		memset(msg.mtext,0,20); //清空
		r = msgrcv(msgid,&msg,sizeof(msg),TYPEA,IPC_NOWAIT);
		printf("r:%d,msg:%s,typs:%d\n",r,msg.mtext,msg.mtype);
		sleep(1);
	}

	return 0;
}

三:信号量 sem

1.创建key

2.创建信号量   semget

3.初始化信号量  semctl

4.使用信号量  semop

5.删除信号量semctl

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

       int semget(key_t key, int nsems, int semflg);
 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/types.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
                                           (Linux-specific) */
           };

struct semb{
	       unsigned short  semval;   /* semaphore value */
           unsigned short  semzcnt;  /* # waiting for zero */
           unsigned short  semncnt;  /* # waiting for increase */
           pid_t           sempid;   /* ID of process that did last op */
	       unsigned short sem_num;  /* semaphore number */
           short          sem_op;   /* semaphore operation */
           short          sem_flg;  /* operation flags */

};
int main()
{
	//1.创建key
	key_t key = ftok(".",'s');
	if(-1 == key) printf("ftok error:%m\n"),exit(-1);
	printf("ftok %m\n");

	//2创建信号量
	 int semid = semget(key,1,IPC_CREAT|0654);
	//3初始化
	 union semun u;
	 u.val = 5;

	 semctl(semid,0,IPC_SET,&u);

	 //使用
	 struct semb buf;
	 buf.sem_num = 0;  //数组下标
	 buf.sem_op = -1;
	 buf.sem_flg = 0;
	 int n=0;
	 while(1)
	 {
	 	printf("吃了%d个月饼!\n",++n);
	 	semop(semid,&buf,1);
	 }
	

}

                   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值