一、管道:
概念:管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递
特性:
- 管道采用半双工通信方式。因此,数据只能在一个方向上流动
- 只能在有公共祖先的进程间使用管道
- 数据一旦被读走,便不在管道中存在,不可反复读取
1 #include <unistd.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <sys/wait.h>
6
7 void err_sys(const char *str)
8 {
9 perror(str);
10 exit(1);
11 }
12
13 int main()
14 {
15 pid_t pid;
16 char buf[1024];
17 int fd[2];
18 char *p = "test for pipe\n";
19
20 if (-1 == pipe(fd))
21 err_sys("pipe");
22
23 pid = fork();
24 if (pid < 0)
25 {
26 err_sys("fork err");
27 }
28 else if (0 == pid)
29 {
30 close(fd[1]); //child
31 int len = read(fd[0], buf, sizeof(buf));
32 write(STDOUT_FILENO, buf, len);
33 close(fd[0]);
34 }
35 else
36 {
37 close(fd[0]);
38 write(fd[1], p, strlen(p));
39 wait(NULL);
40 close(fd[1]);
41 }
42
43 return 0;
44 }
函数popen和pclose
常见的操作:创建一个连接到另一个进程的管道,然后读其输出或向其输入端发送数据
应用:最常见的应用是在C语言里将shell命令的返回值在C语言里解析;
#include <stdio.h>
FILE *popen(const char *cmdstring, const char *type);
int pclose(FILE *fp);
待写:popen的用法
二、FIFO
概念:FIFO又名有名管道或命名管道,
接口:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
FIFO与管道:
- 和管道一样,FIFO仅提供半双工的数据通信,即只支持单向的数据流;
- 与管道最大的不同:管道只能用于具有亲缘关系的进程间的通信,FIFO可以支持任意两个进程间的通信
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <fcntl.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <sys/stat.h>
7 #include <sys/types.h>
8
9 #define FIFO_PATH "/home/wooya/fifo"
10
11 int main()
12 {
13 if (mkfifo(FIFO_PATH, 0666) < 0 && errno != EEXIST)
14 {
15 printf("create fifo failed ...\n");
16 return -1;
17 }
18
19 if (0 == fork())
20 {
21 int readfd = open(FIFO_PATH, O_RDONLY);
22 printf("child open fifo success....\n");
23
24 char buf[256];
25 read(readfd, buf, sizeof(buf));
26 printf("receive message form pipe:%s\n", buf);
27 close(readfd);
28 }
29
30 sleep(3);
31 int writefd = open(FIFO_PATH, O_WRONLY);
32 printf("parent open fifo success\n");
33 char *temp = "i love you";
34 write(writefd, temp, strlen(temp) + 1);
35 close(writefd);
36 }
三、消息队列
概念:消息队列是消息的链表,存储在内核中,由消息队列标识符标识;
接口:
msgget():函数该函数用来创建和访问一个消息队列
原型:int msgget(key_t key, int msgflg);
msgsnd()函数该函数用来把消息添加到消息队列中;
原型:int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
msgrcv()函数该函数用来从一个消息队列获取消息;
原型:int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
msgctl()函数该函数用来控制消息队列,它与共享内存的shmctl函数相似
原型:int msgctl(int msgid, int command, struct msgid_ds *buf);
四、信号量
概念:防止出现因多个程序同时访问一个共享资源而引发的一系列问题,它是一个计数器,用于为多个进程提供对共享数据对象的访问;
接口:
semget()函数它的作用是创建一个新信号量或取得一个已有信号量;
semop()函数它的作用是改变信号量的值;
semctl()函数该函数用来直接控制信号量信息;
五、共享内存
概念:共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc()分配的内存一样
接口:
shmat()函数第一次创建完共享内存时,它还不能被任何进程访问,shmat()函数的作用就是用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间;
shmdt()函数该函数用于将共享内存从当前进程中分离。注意,将共享内存分离并不是删除它,只是使该共享内存对当前进程不再可用;
shmctl()函数与信号量的semctl()函数一样,用来控制共享内存;