进程间通信(系统编程)

进程间通信:用户空间不可以通信,只在内核中通信

线程间通信:用户空间可以通信,通过全局变量进行通信

要想实现父进程先运行子进程后运行,可以加一个全局变量或者局部变量阻塞子进程的运行。

通信方式:管道、信号、IPC(共享内存,消息队列,信号灯)

占用内存的只有目录文件,软链接,套接字文件?

有名管道,字符设备,块设备,套接字他们不占用磁盘空间,只有文件节点

atoi(字符串):将字符串转换为数字
sprintf(buf,"%d",num);将数字转化为字符串

无名管道:pipe(pipefd) pipefd[0]读 pipefd[1]写

1.不能实现父子进程之间的通信

2.进程结束管道就不存在了

3.如果管道没有东西可读就会阻塞

&无名管道最大缓存写阻塞是5456左右就会跳出循环

有名管道:mkfifo(路径,权限);

信号:kill(pid,发送哪种信号)

信号的发送:kill(pid,sig) raise(sig) alarm(时间)

信号的接收:pause,sleep,while,

信号的处理:signal(信号值,函数指针) 信号值:处理哪个信号 函数指针:如何处理函数

SIG_IGN:忽略该信号(不执行) SIG_DFL:采用默认方式处理信号(终止进程)

进程间通信

查看IPC对象:ipcs    -m(共享内存)            -q(消息队列)              -s(信号灯)

删除IPC对象: ipcrm      -m/-q/-s       id

例:system("ipcs -m");

共享内存

创建:     shmget(key_t key,size,flg);

        key: IPV_PRIVATE (key始终为0)  或   ftok(路径,一个字符)的返回key值   

        :使用key传入时,第三个参数需要使用IPC_CREAT |0777

        size:共享内存的大小

        flg:权限

        成功返回ID

申请地址空间:        shmat:将共享内存映射到用户空间的地址中

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

        ①:ID    ② 映射的地址,NULL自动完成  ③:SHM_RDONLY 或者默认0

        成功返回映射的地址

删除:        int shmdt((const void *shmaddr)     //将用户空间的缓存释放

删除:         int shmctl(int shmid, int cmd, struct shmid_ds *buf); //将内核空间的缓存释放

        cmd:IPC_STAT(获取对象属性)    IPC_SET(设置对象属性)     IPC_RMID(删除对象)

        buf: 指定IPC_STAT/IPC_SET时用以保存/设置属性

消息队列

创建:      int msgget(key_t key, int msgflg);
                msgflg:访问权限

                成功返回队列ID

删除:     int msgctl(int msqid, int cmd, struct msqid_ds *buf);   

cmd:  IPC_STAT:读取消息队列的属性,将其保存到buf  

        IPC_SET:设置消息队列的属性,取buf的参数

        IPC_RMID:从系统中删除消息队列

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

msgp:指向消息的指针   struct msgbuf {
               long mtype;       消息类型
               char mtext[1];    消息正文
           };
 size:发送的字节数

flg:IPC_NOWAIT  消息没有发送完成也会返回   0:发送完成才会返回

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

msgp:读到哪里去缓存

msgz:想读多少个

msgtype:0接收第一个消息  >0 接收第一个类型为msgtype的消息  <0

msgflg:  0阻塞        

成功返回读取的字节数

信号灯

创建:        int semget(key_t key, int nsems, int semflg);

nsems:信号灯集中包含的信号灯数目

semflg:访问权限

成功返回信号灯集ID

删除或初始化:        int semctl(int semid, int semnum, int cmd, ...);

        semnum:要修改的信号灯编号     默认0

        cmd:GETVAL:获取信号灯的值     SETVAL:设置信号灯的值     IPC_RMID:从系统中删除信号灯的集合

成功返回0

信号灯的P操作:        int semop(int semid, struct sembuf *sops, size_t nsops);

struct sembuf{         

  unsigned short sem_num;  信号灯的编号
           short          sem_op;   0等待  知道信号灯的值为0  1释放资源    V操作   -1  P操作
           short          sem_flg;    IPC_NOWAIT   SEM_UNDO

}

nsops:操作信号灯的个数


 

        

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值