进程间通信
每个进程的地址空间都是独立的,所以要通信,就要通过内核实现
管道
匿名管道:比如dmesg | grep ov13850命令中的|就是一个管道;也可通过int pipe(int fd[2])系统调用创建两个读写的文件描述符,通过fork创建子进程,会复制文件描述符,直接在各自进程读写,就达到了通信的目的,由于是fifo所以不能lseek等操作
命名管道:通过int mkfifo( const char *pathname, mode_t mode)创建类型为管道的文件,在各自进程打开这个文件,读写就能通信了
消息队列
就是保存在内核中的消息链表;通过int msgget(key_t key, int msgflg);打开一个现存队列或新建一个队列
再通过int msgsnd(int msgid, const void* msgp, size_t msgsz, long msgtyp, int msgflg)和int msgrcv(int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)发送和接收消息
与管道不同的是消除了管道的同步和阻塞问题,而且可以有选择的接收数据
共享内存
以上两种都会产生用户态跟内核态之间的数据复制操作,共享内存让不同进程的用户虚拟地址去映射同一块物理内存;通过指针读写,大大提高通信效率;对于产生的竞争操作可通过信号量来实现对共享资源的同步与互斥
通过int shmget( key_t, size_t, flag)打开或新建一块内核空间;再通过void *shmat(int shmid,const void *shmaddr,int shmflg)返回当前进程的一个用户虚拟地址,再操作指针就可以了
信号
是唯一的异步通信机制,比如通过ctrl + c,kill
Socket
服务端通过socket,bind,listen,accept,客户端通过connect建立连接,再通过read,write进行读写操作,达到通信的目的