|
匿名管道pipe
具有亲缘关系的两个进程间通信,半双工通信,要实现全双工通信需要创建两个pipe。
相关系统调用
函数名作用fork()复制一个子进程。pipe()创建一个管道。close()用于关闭管道读/写端。write()向管道写入。read()从管道读出。实例
- #include <sys/types.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- int main() {
- int result = -1;
- char str[] = "hello,process!"; //要写入的数据
- char buf[256]; //读出缓冲区
- int fd[2]; //读/写文件描述符
- int *pipe_read = &fd[0]; //管道读写指针,便于区分读写文件描述符
- int *pipe_write = &fd[1];
- pid_t pid = -1; //进程号,用于标识子进程与父进程
- result = pipe(fd); //创建管道
- if(result != 0) {
- printf("open pipe ERROR\n");
- exit(0);
- }
- pid = fork(); //创建子进程
- if(pid == -1) {
- printf("create process ERROR\n");
- exit(0);
- }
- if(pid == 0) { //子进程
- close(*pipe_read); //关闭通道读功能
- write(*pipe_write, str, strlen(str)); //管道写
- close(*pipe_write); //写完关闭文件描述符
- }else {
- close(*pipe_write);
- read(*pipe_read, buf, sizeof(buf));
- close(*pipe_read);
- printf("收到子进程数据:%s", buf);
- }
- return 0;
- }
复制代码 运行结果:- [Running] cd "/home/tayoou/pipe/" && gcc pipe.c -o pipe && "/home/tayoou/pipe/"pipe
- 收到子进程数据:hello,process!
复制代码 命名管道fifo
无亲缘关系的进程间进行通信,是一种特殊的文件,在文件系统中以文件名的形式存在,数据存储在内存中,命名管道可以在终端创建或程序中创建。
相关函数
函数名功能mkfifo()创建一个命名管道。open()打开一个命名管道(文件)。read()读命名管道(文件)。write()写命名管道(文件)。实例
fifo_write.c- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- int main() {
- int result = -1;
- int fifo_fd = -1; //命名管道文件描述符
- char str[] = "hello fifo!";
- result = mkfifo("myfifo", 0666); //创建命名管道,读写权限拉满,由于命名管道不可执行,因此不是0777
- if(result != 0) {
- printf("create mkfifo FAIL\n");
- exit(0);
- }
- fifo_fd = open("myfifo", O_WRONLY); //只写打开命名管道
- //fifo_fd = open("myfifo", O_WRONLY | O_NONBLOCK); //非阻塞方式写
-
- if(fifo_fd == -1) {
- printf("open fifo FAIL\n");
- exit(0);
- }
-
- result = write(fifo_fd, str, strlen(str)); //向命名管道写
- if(result == -1) {
- printf("write fifo FAIL\n");
- exit(0);
- }
-
- printf("write %s to fifo\n", str);
- close(fifo_fd);
- return 0;
- }
复制代码 fifo_read.c- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- int main() {
- int read_fd = -1;
- int result = -1;
- char buf[256];
- read_fd = open("myfifo", O_RDONLY); //打开命名管道,只读
- if(read_fd == -1) {
- printf("open fifo FAIL\n");
- exit(0);
- }
-
- memset(buf, 0, sizeof(buf)); //数组初始化
- result = read(read_fd, buf, sizeof(buf)); //从命名管道读
- //fifo_fd = open("myfifo", O_WRONLY | O_NONBLOCK); //非阻塞方式读
- if(result == -1) {
- printf("read fifo FAIL\n");
- exit(0);
- }
- printf("recive %s from fifo\n", buf);
- close(read_fd);
- return 0;
- }
复制代码 运行结果:- tayoou@:~/fifo$ ./fifo_write
- write hello fifo! to fifo
- tayoou@:~/fifo$ ./fifo_read
- recive hello fifo! from fifo
复制代码 消息队列MQ
相关函数
函数名功能msgget()创建/获取消息队列msgsnd()发送消息到消息队列msgrcv()从消息队列获取消息msgctl()控制消息队列(包括删除)实例
mq_send.c- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- struct mq_send
- {
- long type; //消息类型,用来表示某一类消息
- char data[256]; //消息内容
- };
- int main() {
- int qid = -1; //消息队列ID
- struct mq_send msg;
- int result = -1;
- qid = msgget((key_t)1234, IPC_CREAT | 0666); //创建消息队列,用key值来唯一标识一个消息队列,权限为0666
- if(qid == -1) {
- printf("creat msgget FAIL\n");
- exit(0);
- }
- while(1) {
- memset(msg.data, 0, sizeof(msg.data)); //初始化数组
- if(fgets(msg.data, sizeof(msg.data), stdin) == NULL) { //获取键盘输入
- printf("stdin FAIL\n");
- exit(0);
- }
- msg.type = getpid(); //获得进程号,此步并非必须,可以设置type为大于0的任意值
- result = msgsnd(qid, &msg, sizeof(msg.data), 0); //发送data到mq
- if(result == -1) {
- printf("send msg FAIL\n");
- exit(0);
- }
- printf("send msg to mq: %s", msg.data);
- if(strcmp(msg.data, "quit\n") == 0) { //退出判断逻辑
- printf("quit SUCCESS\n");
- exit(0);
- }
- }
- }
复制代码 mq_rcv.c- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- struct mq_rcv
- {
- long type;
- char data[256];
- };
- int main() {
- int qid = -1;
- struct mq_rcv msg;
- int result = -1;
- qid = msgget((key_t)1234, IPC_CREAT | 0666); //使用相同的消息队列key值获取消息队列ID
- if(qid == -1) {
- printf("creat mq FAIL\n");
- exit(0);
- }
- while(1) {
- result = msgrcv(qid, &msg, sizeof(msg.data), 0, 0); //从消息队列获取消息,第四个0(type)表示不按类型取,直接取mq的第一个消息。第五个0(msgflg)表示使用默认方式(阻塞)获取消息。
- if(result == -1) {
- printf("read mq FAIL\n");
- exit(0);
- }
- printf("recive data from mq: %s", msg.data);
- if(strcmp(msg.data, "quit\n") == 0) {
- msgctl(qid, IPC_RMID, NULL); //删除消息队列。
- printf("close mq SUCCESS\n");
- break;
- }
- }
- return 0;
- }
复制代码 运行结果:- tayoou@:~/mq$ ./mq_send
- test
- send msg to mq: test
- nihao
- send msg to mq: nihao
- :)
- send msg to mq: :)
- quit
- send msg to mq: quit
- quit SUCCESS
复制代码- tayoou@:~/mq$ ./mq_rcv
- recive data from mq: test
- recive data from mq: nihao
- recive data from mq: :)
- recive data from mq: quit
- close mq SUCCESS
复制代码 进程信号量 system-V
本质是计数器,用于保护临界资源。不同于全局变量,信号量的P/V是原子操作。区别于线程POSIX信号量。
相关函数
函数名功能semget()创建、获取信号量集semop()进行PV操作semctl()管理信号量示例
来源:https://www.cnblogs.com/Tayoou/p/17745144.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|