IPC进程间通信 system V IPC

包含三个方面:1.消息队列  2.共享内存  3.信号量集

使用命令ipcs 可以查看system  v TPC的对象

第一步:获取一个键值

如何获取键值?使用ftok(3)获取一个键值

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

 key_t ftok(const char *pathname, int proj_id);

功能:转换pathname和proj_id为一个key值。

参数:

pathname:指定文件的名字

proj_id:一个整数,这个整数的低八位不能为0 

返回值:

成功   key值返回

-1  失败   errno被设置

举例使用ftok(3)  获取一个键值

 

第二步:通过键值获取一块内存,将这块内存的id返回。

第三步:通过内存的id操作这块内存。

1.消息队列

通过键值获取一块内存,将这块内存的id返回。需要使用msgget(2),获取内核对象的id

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

 int msgget(key_t key, int msgflg);

功能:获取一个消息队列的id
参数:

key:fotk(3)获得key值

msgflg:

IPC_CREAT:

IPC_EXCL:

mode:指定了消息队列的权限

返回值:

-1  失败  errno被设置

成功返回消息的队列的id

举例验证,通过键值获取消息队列的id

向消息队列中发送消息,使用msgsnd(2)

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

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

功能:向消息队列发送消息

参数:

msqid:指定了要操作的消息队列的id

msgp:指向msgbuf类型的指针

 msgsz:是metxt的长度

msgflg:

返回值:

0  成功

-1   失败  errno被设置

举例验证,将一个消息放入消息队列中。

 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

功能:从消息队列中获取消息

参数:

msqid:制定了消息队列的id

msgp:指向了获取到的消息

msgsz:是mtext的长度

msgtyp:消息的类型

msgflg:

IPC_NOWAIT:如果消息队列中没有消息,立即返回。

0  :如果消息队列中没有消息,阻塞等待。

返回值:

-1 错误  errno 被设置

获取到的消息体的字节数

举例从消息队列中获取消息输出到显示器

补充:
  struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[1];    /* message data */
           };
 

2.共享内存

根据键值获取共享内存的id,如何获取?使用shmget(2)

 #include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);

功能:

参数:

key:ftok(3)返回的键值

size:指定了共享内存的尺寸

shmflg:

 IPC_CREAT :指定创建共享内存段

返回值:

-1  错误  

返回共享内存段的id

 

举例,创建共享内存段

将共享内存映射到进程的虚拟地址空间里,使用shmat(2)
       #include <sys/types.h>
       #include <sys/shm.h>

       void *shmat(int shmid, const void *shmaddr, int shmflg);

功能:将共享内存绑定到进程的地址空间里

参数:

shmid:共享内存的id

shmaddr:指定了进程绑定共享内存的地址。指定为空,系统做选择。

shmflg:

返回值:

返回和共享内存段绑定的地址

 (void *) -1   错误    errno被设置 

       int shmdt(const void *shmaddr);
功能:解除和共享内存段的绑定

参数:shmaddr:指定了要解除共享内存段在进程中的地址

返回值:

0  成功

-1   失败  errno被设置

举例使用共享内存实现进程间的通信。shmA.c  shmB.c

ipcrm 用来从内核中移除ipc通讯对象。

 

3.信号量集

信号量集就是有一个或多个信号量组成的集合。

如何使用信号量集是实现进程间的通讯?

1.获取一个键值

2.通过键值获取信号量集semid 

semget(2)

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

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

3.对信号量集中的某个信号量进程pv操作。semop(2)

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

 int semop(int semid, struct sembuf *sops, unsigned nsops);

功能:信号量的操作

参数:

semid:制定了信号量集的id

sops:制定了对信号量的操作

nsops:指定了要操作的信号量的个数。

返回值:

0  成功

-1  失败  errno被设置

补充:

 unsigned short  semval;   /* semaphore value */
 unsigned short  semzcnt;  /* # waiting for zero */
 unsigned short  semncnt;  /* # waiting for increase */
 pid_t           sempid;   /* process that did last op */

 

struct sembuf{

unsigned short sem_num;  /* semaphore number */
short          sem_op;   /* semaphore operation */
short          sem_flg;  /* operation flags */

};

sem_num  指定了要操作的信号量的下标

sem_op   指定了对信号量的pv操作

>0  semval+sem_op   v 操作

=0  进程等待到零  立即处理。 

<0  如果sem_op 的绝对这小于semval  立即处理。semval-sem_op  p操作   

     如果sem_op的绝对值大于semval,IPC_NOWAIT被指定,semop(2)立即返回错误。
sem_flg  IPC_NOWAIT(非阻塞) and SEM_UNDO()为零时,阻塞。

 

4.为信号量集中的某个信号量设置初值。或者获取信号量的值。

为了信号量中的某一个信号量设置初值。或者获取信号量的值。控制信号量集中某一个信号量,需要使用到semxtl(2)

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

 int semctl(int semid, int semnum, int cmd, ...);

 

补充:

第四个参数:

  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) */
           };

 

举例,使用信号量集实现进程间的通信

client.c

sever.c

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值