前车之鉴, 后车之师
0. 概述
1. 管道
1.1.1匿名管道概念
1.1.2匿名管道代码实现
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5
6
7 int main()
8 {
9 // 创建管道
10 int pipefd[2] = { 0 };
11 int ret = pipe(pipefd);
12 if (ret < 0)
13 {
14 perror("pipe error");
15 return -1;
16 }
17
18 int pid = fork();
19 if (pid < 0)
20 {
21 perror("fork error");
22 return -1;
23 }
24 else if (pid == 0)
25 {
26 //子进程
27 char buf[1024] = { 0 };
28 int ret = read(pipefd[0], buf, 1023);
29 printf("buf:[%s]-[%d]\n", buf, ret);
30 }
31 else
32 {
33 //父进程
34 char* ptr = "今天天气好晴朗";
35 write(pipefd[1], ptr, strlen(ptr));
36 }
37
38
39
40 return 0;
41 }
- 效果: 子进程读取了父进程的消息
1.2.1命名管道概念
1.2.2命名管道代码
- fifo_wirte.c
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <sys/stat.h>
6 #include <errno.h>
7 #include <fcntl.h>
8
9
10 int main()
11 {
12 umask(0);
13 const char* file = "./test.fifo";
14 int ret = mkfifo(file, 0664);
15 if (ret < 0 && errno != EEXIST)
16 {
17 perror("mkfifo error");
18 }
19
20 int fd = open(file, O_WRONLY);
21 if (fd < 0)
22 {
23 perror("open error");
24 return 0;
25 }
26 printf("open fifo success\n");
27
28 while(1)
29 {
30 char buf[1024] = {0};
31 scanf("%s", buf);
32 ret = write(fd, buf, strlen(buf));
33 if (ret < 0)
34 {
35 perror("read error");
36 return -1;
37 }
38 }
39
40 close(fd);
41 return 0;
42 }
- fifo_read.c
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <sys/stat.h>
6 #include <errno.h>
7 #include <fcntl.h>
8
9
10 int main()
11 {
12 umask(0);
13 const char* file = "./test.fifo";
14 int ret = mkfifo(file, 0664);
15 if (ret < 0 && errno != EEXIST)
16 {
17 perror("mkfifo error");
18 }
19
20 int fd = open(file, O_RDONLY);
21 if (fd < 0)
22 {
23 perror("open error");
24 return 0;
25 }
26 printf("open fifo success\n");
27
28 while(1)
29 {
30 char buf[1024] = {0};
31 ret = read(fd, buf, 1023);
32 if (ret < 0)
33 {
34 perror("read error");
35 return -1;
36 }
37 else if(ret == 0)
38 {
39 printf("all write close\n");
40 return -1;
41 }
42 printf("buf:[%s]\n", buf);
43 }
44
45 close(fd);
46 return 0;
47 }
- makefile
1 ALL:fifo_write fifo
2 fifo_write:Fifo_write.c
3 gcc $^ -o $@
4 fifo:Fifo.c
5 gcc $^ -o $@
- 效果: 在fifo_wirte运行后输入若干字符串, 在fifo_read运行后能够读取并打印字符串
2. 共享内存
- 共享内存的操作函数
- 其他特点
2.1共享内存代码
- shm_wirte.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <sys/shm.h>
5
6
7 #define IPC_KEY 0x12345678
8 #define PROJ_ID 0x12345678
9 // 创建唯一标识
10
11 int main()
12 {
13 // 创建共享内存
14 int shmid = shmget(IPC_KEY, 32, IPC_CREAT|0664);
15 if (shmid < 0)
16 {
17 perror("shmget error");
18 return -1;
19 }
20
21 // 映射共享内存
22 void* shmstart = shmat(shmid, NULL, 0);
23 if (shmstart == (void*)-1)
24 {
25 perror("shmat error");
26 return -1;
27 }
28 while (1)
29 {
30 printf("%s", shmstart);
31 sleep(1);
32 }
33 shmdt(shmstart);// 接触映射
34 shmctl(shmid, IPC_RMID, NULL);// 删除共享内存
35
36 return 0;
37 }
- shm_read.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <sys/shm.h>
5
6
7 #define IPC_KEY 0x12345678
8 #define PROJ_ID 0x12345678
9 // 创建唯一标识
10
11 int main()
12 {
13 // 创建共享内存
14 int shmid = shmget(IPC_KEY, 32, IPC_CREAT|0664);
15 if (shmid < 0)
16 {
17 perror("shmget error");
18 return -1;
19 }
20
21 // 映射共享内存
22 void* shmstart = shmat(shmid, NULL, 0);
23 if (shmstart == (void*)-1)
24 {
25 perror("shmat error");
26 return -1;
27 }
28 int i = 0;
29 while (1)
30 {
31 sprintf(shmstart, "%s-%d\n", "share memory", i++);
32 sleep(1);
33 }
34 shmdt(shmstart);// 接触映射
35 shmctl(shmid, IPC_RMID, NULL);// 删除共享内存
36
37 return 0;
38 }
- makefile
1 ALL:shm_read shm_write
2 shm_write:shm_write.c
3 gcc $^ -o $@
4 shm_read:shm_read.c
5 gcc $^ -o $@
- 效果: shm_read一直在更新共享内存, shm_write会将共享内存的消息不断打印到屏幕上