我是靠谱客的博主 完美信封,这篇文章主要介绍Linux进程间通信,现在分享给大家,希望可以做个参考。

进程间通信

1.管道

1.方法
复制代码
1
2
3
4
#include <unistd.h> int pipe(int pipefd[2]);

管道是半双工的,只能在具有公共祖先的进程间使用。

pipefd[2]:传入大小为2的int数组,返回两个文件描述符,pipefd[0]为读端,pipefd[1]为写端。

2.实例

1.创建一个管道,用于父子进程间数据传输。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <wait.h> #include <string.h> #define BUF_SIZE 20 int main(int argc, char const *argv[]) { int pipefd[2]; pid_t pid; int err; char buf[BUF_SIZE]; err = pipe(pipefd); if(err < 0){ perror("pipe()"); exit(1); } pid = fork(); if(pid < 0){ perror("fork"); exit(1); } if(pid > 0){//parent close(pipefd[0]);//父进程关闭读端 write(pipefd[1], "Hellon", 7);//往管道写端写入数据 waitpid(pid, NULL, 0);//0,表示父进程等待子进程终止 }else{ close(pipefd[1]);//子进程关闭写端 read(pipefd[0], buf, BUF_SIZE);//从管道读端读出数据 puts(buf); } exit(0); }

2.使用管道实现父子进程间同步,如顺序输出abababab。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <wait.h> #include <string.h> static int fd_c[2], fd_p[2]; static int tell_wait() { if (pipe(fd_c) < 0 || pipe(fd_p) < 0) return -1; return 0; } static void wait_child() { char c; //读子进程管道,如果管道中没有数据,父进程将会阻塞在这儿,直到子进程往管道中写入数据 if (read(fd_c[0], &c, 1) != 1) { perror("read fd_c"); exit(1); } if (c != 'c') { fprintf(stderr, "wait child: incorrect data.n"); } } static void tell_parent() { //往子进程管道中写入数据,父进程将会解除阻塞 if (write(fd_c[1], "c", 1) != 1) { perror("write fd_c"); exit(1); } } static void wait_parent() { char c; if (read(fd_p[0], &c, 1) != 1) { perror("read fd_p"); exit(1); } if (c != 'p') { fprintf(stderr, "wait parent: incorrect data.n"); } } static void tell_child() { if (write(fd_p[1], "p", 1) != 1) { perror("write fd_p"); exit(1); } } int main(int argc, char const *argv[]) { int err; pid_t pid; err = tell_wait(); int i = 0; if (err < 0) { fprintf(stderr, "tell_wait()n"); exit(err); } pid = fork(); if (pid < 0) { perror("fork()"); exit(1); } if (pid > 0) { while (i < 10) { putchar('a'); fflush(stdout);//由于标准输出时行缓冲模式,所以每输出一个字节,需要flush一下 sleep(1); tell_child(); wait_child(); i++; } wait(NULL);//等待子进程执行完,回收 puts("");//打印换行符 } else { while (i < 10) { wait_parent(); putchar('b'); fflush(stdout); sleep(1); tell_parent(); i++; } } return 0; } 运行结果: shbj@ubuntu:~/develop/workspace/c/ipc$ ./pipe2 abababababababababab

2.FIFO

通FIFO文件,不相关的进程也能交换数据。

1.方法
复制代码
1
2
3
4
5
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);

pathname : 指定FIFO文件的创建路径。

mode : FIFO文件权限。

2.实例

1.通过FIFO,将实现文件的复制,并将复制文件中的小写字母转换为大写字母。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <wait.h> #define PATH "/tmp/fifo1" #define BUF_SIZE 1024 static int dest_fd1, sou_fd, fifo_fd; static int i; static char buf[BUF_SIZE]; static void write_fun(const char *path) { char c; fifo_fd = open(PATH, O_WRONLY);//以只写形式打开管道 int rang; if (fifo_fd < 0) { perror("open fifo"); exit(1); } sou_fd = open(path, O_RDONLY); if (sou_fd < 0) { perror("open source"); exit(1); } rang = 'z' - 'Z'; while ((i = read(sou_fd, &c, 1)) > 0)//从原文件中一个字节一个字节的读出数据 { if (c < 'z' && c > 'a')//判断是否为小写字母 c -= rang;//转换为大写 write(fifo_fd, &c, i);//写入管道 } close(fifo_fd); close(sou_fd); } static void read_fun(const char *path) { fifo_fd = open(PATH, O_RDONLY);//以只读形式打开管道 if (fifo_fd < 0) { perror("open fifo"); exit(1); } dest_fd1 = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0660); if (dest_fd1 < 0) { perror("open dest"); exit(1); } while ((i = read(fifo_fd, buf, BUF_SIZE)) > 0)//从管道中读出数据 { write(dest_fd1, buf, i);//写入目标文件 } close(fifo_fd); close(dest_fd1); } int main(int argc, char const *argv[]) { pid_t pid; int err, i; if (access(PATH, F_OK) < 0) { err = mkfifo(PATH, 0660); if (err < 0) { perror("mkfifo()"); exit(1); } } for (i = 0; i < 2; i++)//创建两个子进程 { if ((pid = fork()) < 0) { perror("fork()"); exit(1); } if (pid == 0) { if (i == 0){//一号子进程写管道 sleep(2); write_fun(argv[1]); exit(0); } else if (i == 1){//二号子进程读管道 sleep(2); read_fun(argv[2]); exit(0); } } } //由于父进程没有调用wait()等待回收子进程,所以当父进程退出后,子进程会变成孤儿进程,子进程会被init进程托管。 return 0; }

3.消息队列

1.方法
复制代码
1
2
3
4
5
#include <sys/types.h> #include <sys/ipc.h> //根据一个指定的文件路径,得到一个key,主要是利用文件i_node的唯一性,使key也唯一。 key_t ftok(const char *pathname, int proj_id);

path:文件路径。

proj_id:相当于一个hash的混淆值,一般传入一个字符。

复制代码
1
2
3
4
5
6
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> //根据ftok返回的key,得到id。 int msgget(key_t key, int msgflg);

key:ftok返回的key;如果是有亲缘关系进程间可以使用IPC_PRIVATE。

msgflg:接收端,使用和文件一样的权限位(如0660),如果消息队列以前不存在需要或上IPC_CREATE(0660 |IPC_CREATE);发送端,一般设为0就好。

复制代码
1
2
3
4
5
6
7
8
9
10
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> 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);

msgp:传输数据的指针。

msgsz:数据的大小,需要减去mtype的大小,sizeof(buf) - sizeof(long);

msgflg:

0:接收端,msgrcv将会阻塞,直到队列中有msgtyp对应的消息;

​ 发送端,当消息队列满时,msgsnd将会阻塞,直到有消息被取走。

IPC_NOWAIT:接收端,没有对应消息,msgrcv不等待,立即返回;

​ 发送端,当消息队列满时,msgsnd不等待,立即返回。

复制代码
1
2
3
4
5
6
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buf);

cmd:IPC_STAT、IPC_SET、IPC_RMID。

buf:如果不关心,可以传NULL。

2.实例

1.两个不相关进程间数据传输。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//头文件 #ifndef MSG1_H__ #define MSG1_H__ #define PATH "/etc/services" #define PROJ_ID 'a' struct stu_st { char name[20]; int math; int chinese; }; struct msg_stu { long mtype; struct stu_st st; }; #endif
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//接收端 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> #include <errno.h> #include "msg1.h" int main(int argc, char const *argv[]) { key_t key; int id; int err; struct msg_stu *stp; key = ftok(PATH, PROJ_ID); if (key < 0) { perror("ftok()"); exit(1); } id = msgget(key, 0660 | IPC_CREAT); if (id < 0) { perror("msgget()"); exit(1); } stp = malloc(sizeof(*stp)); while((err = msgrcv(id, stp, sizeof(*stp) - sizeof(long), 1, 0)) < 0){ if(err != EINTR){ perror("msgrcv()"); msgctl(id, IPC_RMID, NULL); exit(1); } } msgctl(id, IPC_RMID, NULL); printf("name: %s, chinese : %d, math : %dn", stp->st.name, stp->st.chinese, stp->st.math); return 0; }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//发送端 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> #include <errno.h> #include "msg1.h" int main(int argc, char const *argv[]) { key_t key; int id; int err; struct msg_stu *stp; key = ftok(PATH, PROJ_ID); if (key < 0) { perror("ftok()"); exit(1); } id = msgget(key, 0); if (id < 0) { perror("msgget()"); exit(1); } stp = malloc(sizeof(*stp)); stp->mtype = 1; strcpy(stp->st.name, "zhangsan"); stp->st.math = 90; stp->st.chinese = 80; //如果被信号打断在重新发送 while ((err = msgsnd(id, stp, sizeof(*stp) - sizeof(long), 0)) < 0) { if (err != EINTR) { perror("msgrcv()"); exit(1); } } return 0; }

4.信号量

1.方法

1.获取信号量列表。

复制代码
1
2
3
4
5
6
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semget(key_t key, int nsems, int semflg);

nsems:信号量列表中信号量的个数。

semflg:相当于文件的权限位;亲缘关系的进程(如父子进程)key可为IPC_PRIVATE,semflg可以不或上IPC_CREATE,其余需要,如0660|IPC_CREATE。

2.控制信号量列表。

复制代码
1
2
3
4
5
6
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semctl(int semid, int semnum, int cmd, ...);

semid:信号量id。

semnum:哪一个信号量,信号量下标。

cmd:命令,IPC_STAT、IPC_SET、IPC_RMID、GETALL、GETVAL、SETALL、SETVAL。

返回值:根据命令的不同返回值不同。

3.操作信号量列表。

复制代码
1
2
3
4
5
6
7
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semop(int semid, struct sembuf *sops, unsigned nsops);

sops:有如下几个成员

​ sem_num,信号量编号;
​ sem_op,操作,正数+,负数-;
​ sem_flg,选项;

nsops:sops的大小。

2.实例

1.多进程间的顺序累加。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/sem.h> #include <fcntl.h> #include <wait.h> #include <errno.h> #define BUFFSIZE 10 #define PROCNUM 20 static int sem_id; static void P() { struct sembuf buf; buf.sem_num = 0;//下标为0的信号量 buf.sem_op = -1;//信号减1 buf.sem_flg = 0;//无特殊需求 while (semop(sem_id, &buf, 1) < 0)//操作信号量列表。总的又几个信号量,只有1个信号量 { if (errno == EINTR || errno == EAGAIN) continue; perror("semop()"); exit(1); } } static void V() { struct sembuf buf; buf.sem_num = 0; buf.sem_op = 1;//信号加1 buf.sem_flg = 0; while (semop(sem_id, &buf, 1) < 0) { if (errno == EINTR || errno == EAGAIN) continue; perror("semop()"); exit(1); } } int main(int argc, char const *argv[]) { FILE *fp; char buf[BUFFSIZE]; int num; int i; pid_t pid; //key_t key; //key = ftok("/etc/services", 'a');//无亲缘关系的进程,需要获取一个key //sem_id = semget(key, 1, 0660 | IPC_CREATE);//0660 | IPC_CREATE0660 sem_id = semget(IPC_PRIVATE, 1, 0660); //无亲缘关系的进程key设为IPC_PRIVATE,获取信号量列表 if (sem_id < 0) { perror("semget()"); exit(1); } if (semctl(sem_id, 0, SETVAL, 1) < 0)//初始化列表中下标为0的信号量,初始值为1。 { perror("semctl()"); exit(1); } for (i = 0; i < PROCNUM; i++)//创建多个进程,对指定文件中的数据累加 { pid = fork(); if (pid < 0) { perror("fork()"); exit(1); } if (pid == 0) { fp = fopen("/tmp/out", "r+"); if (fp == NULL) { perror("fopen()"); exit(1); } P();//获取信号量,信号量为0时阻塞 fgets(buf, BUFFSIZE, fp); fseek(fp, 0, SEEK_SET); num = atoi(buf); fprintf(fp, "%dn", ++num); fflush(fp); sleep(1); V();//归还信号量,信号量+1 fclose(fp); exit(0); } } for (i = 0; i < PROCNUM; i++) wait(NULL);//回收子进程 semctl(sem_id, 0, IPC_RMID); return 0; } 执行结果: hbj@ubuntu:~/develop/workspace/c/ipc/sem$ echo 10 > /tmp/out shbj@ubuntu:~/develop/workspace/c/ipc/sem$ ./reciver shbj@ubuntu:~/develop/workspace/c/ipc/sem$ cat /tmp/out 30 shbj@ubuntu:~/develop/workspace/c/ipc/sem$

5.共享存储

共享存储允许两个或多个进程共享一个给定的存储区。因为数据不需要在客户进程和服务器进程之间复制,所以这是最快的一种IPC。

共享存储与内存映射的区别,共享存储没有相关的文件,共享存储段是内存的匿名段。

1.方法

1.创建共享存储。

复制代码
1
2
3
4
5
#include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg);

size:存储区大小。

shmflg:权限位。

返回值:成功返回共享存储id,失败-1。

2.操作共享存储。

复制代码
1
2
3
4
5
#include <sys/ipc.h> #include <sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf);

cmd:操作命令;IPC_STAT、IPC_SET、IPC_RMID

buf:cmd为IPC_STAT,将对应共享存储的shmid_ds结构,存储在buf指向的结构中;

​ cmd为IPC_SET,按照buf指向结构中的值,设置共享存储对应的shmid_ds结构。

3.共享存储连接到调用进程的哪个地址上。

复制代码
1
2
3
4
5
6
7
#include <sys/types.h> #include <sys/shm.h> void *shmat(int shmid, const void *shmaddr, int shmflg);//shmid_ds中的shm_nattach +1 int shmdt(const void *shmaddr);//shmid_ds中的shm_nattach -1

shmid:共享存储的id。

shmaddr:指定的地址,一般设为0,由系统自动分配。

shmflg:一般也设为0。

进程中,当共享存储段的操作结束时,调用shmdt与该段分离。注意,调用shmdt并不删除共享存储,只有当某个进程(一般是服务进程)调用了带IPC_RMID命令的shm_ctl特地删除它为止。

2.实例

1.使用共享存储实现不同进程间的数据传输。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#ifndef PROTO_H__ #define PROTO_H__ #define PATH "/etc/services" #define PROJ_ID 'a' struct stu_st { char name[20]; int math; int chinese; }; struct msg_stu { long mtype; struct stu_st st; }; #endif //接收端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include "proto.h" #define PATH "/etc/services" #define SHM_SIZE 1024 int main(int argc, char const *argv[]) { key_t key; int shmid, err; struct stu_st *stp; key = ftok(PATH, 'a'); if (key < 0) { perror("ftok()"); exit(1); } shmid = shmget(key, SHM_SIZE, 0660 | IPC_CREAT); if (shmid < 0) { perror("shmget()"); exit(1); } stp = shmat(shmid, 0, 0); if (stp < 0) { perror("shmat()"); exit(1); } sleep(10); printf("%s, %d, %dn", stp->name, stp->chinese, stp->math); strcpy(stp->name, "lisi"); sleep(10); err = shmdt(stp); if (err < 0) { perror("shmdt()"); exit(1); } err = shmctl(shmid, IPC_RMID, NULL); if (err < 0) { perror("shmctl()"); exit(1); } return 0; } //发送端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include "proto.h" #define PATH "/etc/services" #define SHM_SIZE 1024 int main(int argc, char const *argv[]) { key_t key; int shmid, err; struct stu_st *stp; key = ftok(PATH, 'a'); shmid = shmget(key, SHM_SIZE, 0660); stp = (struct stu_st *)shmat(shmid, 0, 0); strcpy(stp->name, "zhangsan"); stp->chinese = 90; stp->math = 95; sleep(10); printf("%s, %d, %dn", stp->name, stp->chinese, stp->math); err = shmdt(stp); return 0; }

2.改进1程序,实现两个进程间的数据同步,即同时只能有一个进程操作共享存储区。

采用信号量实现同步。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//同步代码 //proto.h #ifndef PROTO_H__ #define PROTO_H__ #define PATH "/etc/services" #define PROJ_ID 'a' struct stu_st { char name[20]; int math; int chinese; }; struct msg_stu { long mtype; struct stu_st st; }; void sem_init(); void sem_destroy(); void P1(); void V1(); void P2(); void V2(); #endif //proto.c #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/sem.h> #include <errno.h> #include "proto.h" static int semid; void sem_init() { key_t key; key = ftok(PATH, PROJ_ID); if (key < 0) { perror("ftok()"); exit(1); } //判断信号量是否创建,创建两个信号量,0信号用于接收端,1信号用于发送端 if ((semid = semget(key, 2, 0660)) < 0) { semid = semget(key, 2, 0660 | IPC_CREAT); } if (semid < 0) { perror("semget()"); exit(1); } if (semctl(semid, 0, SETVAL, 0) < 0)//信号量初值都设为0 { perror("semctl()"); exit(1); } if (semctl(semid, 1, SETVAL, 0) < 0) { perror("semctl()"); exit(1); } } void sem_destroy(){ semctl(semid, 0, IPC_RMID); } //0信号量,初值为0,接收端进程会阻塞 void P1() { struct sembuf buf; buf.sem_num = 0;//0信号 buf.sem_op = -1; buf.sem_flg = SEM_UNDO; while (semop(semid, &buf, 1) < 0) { if (errno == EINTR || errno == EAGAIN) continue; perror("semop_p1()"); exit(1); } } //0信号量+1,唤醒接收端进程 void V1() { struct sembuf buf; buf.sem_num = 0; buf.sem_op = 1; buf.sem_flg = SEM_UNDO; while (semop(semid, &buf, 1) < 0) { if (errno == EINTR || errno == EAGAIN) continue; perror("semop_v1()"); exit(1); } } //1信号量,初值为0,发送端进程会阻塞 void P2() { struct sembuf buf; buf.sem_num = 1; buf.sem_op = -1; buf.sem_flg = SEM_UNDO; while (semop(semid, &buf, 1) < 0) { if (errno == EINTR || errno == EAGAIN) continue; perror("semop_p2()"); exit(1); } } //1信号量+1,唤醒发送端进程 void V2() { struct sembuf buf; buf.sem_num = 1; buf.sem_op = 1; buf.sem_flg = SEM_UNDO; while (semop(semid, &buf, 1) < 0) { if (errno == EINTR || errno == EAGAIN) continue; perror("semop_v2()"); exit(1); } }

接收端

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <sys/sem.h> #include <errno.h> #include "proto.h" #define SHM_SIZE 1024 int main(int argc, char const *argv[]) { key_t key; int shmid, err; struct stu_st *stp; key = ftok(PATH, 'a'); if (key < 0) { perror("ftok()"); exit(1); } shmid = shmget(key, SHM_SIZE, 0660 | IPC_CREAT); if (shmid < 0) { perror("shmget()"); exit(1); } sem_init(); stp = shmat(shmid, 0, 0); if (stp < 0) { perror("shmat()"); exit(1); } P1(); printf("%s, %d, %dn", stp->name, stp->chinese, stp->math); strcpy(stp->name, "lisi"); sleep(5); V2(); err = shmdt(stp); if (err < 0) { perror("shmdt()"); exit(1); } P1(); err = shmctl(shmid, IPC_RMID, NULL); if (err < 0) { perror("shmctl()"); exit(1); } sem_destroy();//接收端销毁信号量 return 0; }

发送端

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include "proto.h" #define SHM_SIZE 1024 int main(int argc, char const *argv[]) { key_t key; int shmid, err; struct stu_st *stp; key = ftok(PATH, 'a'); shmid = shmget(key, SHM_SIZE, 0660); stp = (struct stu_st *)shmat(shmid, 0, 0); sem_init(); strcpy(stp->name, "zhangsan"); stp->chinese = 90; stp->math = 95; sleep(5); V1(); P2(); printf("%s, %d, %dn", stp->name, stp->chinese, stp->math); err = shmdt(stp); V1(); return 0; }

最后

以上就是完美信封最近收集整理的关于Linux进程间通信的全部内容,更多相关Linux进程间通信内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部