Linux系统编程学习之进程间通信
2019-03-13 22:46
106 查看
管道(pipe)
管道的通信方式是单向半双工的,只能一端写入,而另一端读出。
管道分为两种,匿名管道和命名管道
匿名管道
无名管道是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> int main(int argc, char const *argv[]) { int fd[2]; char buf[128] = {0}; if (pipe(fd) == -1) { printf("%s\n", "管道开辟失败"); } pid_t pid = fork(); if (pid > 0) { sleep(1); printf("%s\n", "这是父进程"); close(fd[0]); write(fd[1], "父进程写入", strlen("父进程写入")); }else if (pid == 0) { printf("%s\n", "这是子进程"); close(fd[1]); read(fd[0], buf, 128); printf("读取到的为 == %s\n", buf); } return 0; }
fd(0)是读端,fd(1)是写端,无名管道的使用必须手动关闭不需要的端口,
代码中设定父进程写入,就关闭父进程的读端fd(0),子进程读出,就关闭子进程的写端fd(1);
命名管道
命名管道也被称为FIFO文件,它是一种特殊类型的文件,它在文件系统中以文件名的形式存在,和匿名管道一样,只能一端只读,一端只写,但可以不限于父子进程间的通信,可实现两个不相关进程间的通信。
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *filename, mode_t mode); int mknod(const char *filename, mode_t mode | S_IFIFO, (dev_t)0);
#include <sys/stat.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> int main() { pid_t pid; int ret = mkfifo("./file", 0600); if(ret == -1 && errno != EEXIST){ perror("why"); } pid = fork(); if(pid > 0){ int fd1; fd1 = open("./file", O_WRONLY); while(1){ write(fd1, "hello", 10); sleep(3); } }if(pid == 0){ int fd2; fd2 = open("./file", O_RDONLY); char buf[128] = {0}; sleep(1); while(1){ lseek(fd2, 0, SEEK_SET); read(fd2, buf, 128); printf("child find is %s\n", buf); sleep(3); } } return 0; }
消息队列
消息队列是消息的链表,存放在内存中,由Linux内核维护,每个消息队列都有自己的标识符,消息队列允许一个或多个进程向它写入或者读取消息,消息队列可以实现消息的随机查询。消息不一定要以先进先出的次序读取,编程时可以按消息的类型读取。但是在一个进程对消息队列进行访问的时候,另一个进程无法同时对该消息队列进行访问。
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgget(key_t key, int msgflg); 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); int msgctl(int msqid, int cmd, struct msqid_ds *buf);
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[128]; /* message data */ }; int main(int argc, char const *argv[]) { key_t key; key = ftok(".", 1); int msgId = msgget(key, IPC_CREAT|0777); printf("%x\n",key ); if (msgId == -1) { printf("%s\n", "失败"); } struct msgbuf rcvBuf; msgrcv(msgId, &rcvBuf, sizeof(rcvBuf.mtext), 666,0); printf("接收到的消息是 %s\n", rcvBuf.mtext); msgctl(msgId, IPC_RMID, NULL); return 0; }
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <string.h> struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[128]; /* message data */ }; int main(int argc, char const *argv[]) { key_t key = ftok(".", 1); int msgId = msgget(key, IPC_CREAT|0777); printf("%x\n", key); if (msgId == -1) { printf("%s\n", "失败"); } struct msgbuf sndBuf = {666, "hello world !!"}; msgsnd(msgId, &sndBuf, strlen(sndBuf.mtext), 0); msgctl(msgId, IPC_RMID, NULL); return 0; }
共享内存
共享内存是允许两个不相关进程访问访问同一个一个逻辑内存, 是同时运行的进程数据共享,互相通信的一种非常有效的方式。 共享内存与消息队列不同的地方在于,共享内存可以实现一个进程在对共享内存进行写入操作时,另一个进程可以即时读到写入的消息
shmwrite.c
#include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <string.h> int main(int argc, char const *argv[]) { char *shmaddr; key_t key = ftok(".",1); int shmId = shmget(key, 1024, IPC_CREAT|0600); if (shmId == -1) { printf("%s\n", "共享内存创建失败"); } shmaddr = shmat(shmId, 0, 0); strcpy(shmaddr, "hello world"); printf("%s\n", "写入成功"); sleep(5); shmdt(shmaddr); shmctl(shmId, IPC_RMID,0); printf("%s\n", "退出成功"); return 0; }
shmread.c
#include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> int main(int argc, char const *argv[]) { key_t key = ftok(".",1); int shmId = shmget(key, 1024, 0); char *shmaddr = shmat(shmId, 0, 0); printf("%s\n", "连接成功"); printf("%s\n", shmaddr); shmdt(shmaddr); return 0; }
信号
信号量
相关文章推荐
- linux 系统编程-学习笔记10--进程间通信--管道/FIFO/消息队列/
- 对于系统编程的学习是 选择windows还是linux?
- linux 系统编程学习笔记一
- linux 系统编程学习经验
- 嵌入式系统开发学习步骤(Linux高级编程学习顺序)
- linux系统编程-学习笔记3-dup/dup2/stat/lstat/fstat
- 【Linux 系统编程】shell 脚本基础学习之函数(五)
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】Linux系统调用的实现机制分析
- Linux学习记录--文件管理相关系统编程
- linux 系统编程-学习笔记9--线程的同步互斥锁、读写锁/select/poll
- Linux系统编程——进程间通信:命名管道(FIFO)
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】揭开Linux Proc文件系统的神秘面纱
- 【linux系统编程】进程间通信:信号中断处理
- linux 系统编程学习笔记四
- Linux系统编程学习之《进程环境》
- Linux 系统编程学习-文件操作-DIR等结构体
- linux 系统编程-学习笔记6-main函数/atexit函数/动态库、静态库/
- Linux系统编程——进程间通信:管道(pipe)
- linux系统编程:进程间通信-mmap
- Linux 系统应用编程——进程间通信(下)