linux进程间通信主要有以下几种:
1.共享内存与信号量
两个进程间使用共享内存达到数据共享,通常需要使用信号量进行同步。
使用共享内存的步骤:
获取关键字:通常使用ftok函数,根据不同的文件名和id获取关键字,只要文件名和id都一样,不同程序获得的关键字就相同。
key_t ftok(const char *pathname, int proj_id);
创建:int shmget(key_t key, size_t size, int shmflg);
key:由ftok获得的关键字
size:共享内存大小
shmflg:IPC_CREAT and IPC_EXCL
绑定:void *shmat(int shmid, const void *shmaddr, int shmflg);
将id为shmid的共享内存绑定到返回的地址
id:标识每一个共享内存
shmaddr:指定要绑定的地址,通常设为0,表示系统自动分配
shmflg:读写权限,一般为0,表示可读可写
绑定了之后就可以使用
脱离:int shmdt(const void *shmaddr);
将共享内存从程序空间脱离
销毁:int shmctl(int shmid, int cmd, struct shmid_ds *buf);
根据cmd的不同,可获得共享内存的信息,删除共享内存等
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18
19 struct mymsg
20 {
21 int type;
22 char msg[1020];
23 };
24 int shmid;
25 int semid;
26 struct mymsg *addr = NULL;
27 void sig_int(int sig);
28 void *read_shm(void *arg);
29 void semp();
30 void semv();
31
32 int main()
33 {
34 int ret;
35 // char buf[1024];
36 key_t key;
37 if((key = ftok(".", 1)) == -1)
38 {
39 perror("ftok");
40 exit(1);
41 }
42
43 shmid = shmget(key, 1024, IPC_CREAT | IPC_EXCL | 0777);
44 if(shmid == -1)
45 {
46 if(errno == EEXIST)
47 shmid = shmget(key, 1024, 0);
48 if(shmid == -1)
49 {
50 perror("shmget");
51 exit(1);
52 }
53 }
54 if((addr = shmat(shmid, 0, 0)) == NULL)
55 {
56 perror("shmat");
57 exit(1);
58 }
59 printf("%d %p\n", shmid, addr);
60
61 if((semid = semget(key, 2, IPC_CREAT | IPC_EXCL)) == -1)
62 {
63 if(errno == EEXIST)
64 semid = semget(key, 1, 0);
65 if(semid == -1)
66 {
67 perror("semget");
68 exit(1);
69 }
70 }
71 else
72 {
73 if(semctl(semid, 0, SETVAL, 1) == -1)
74 {
75 perror("semctl");
76 exit(1);
77 }
78 if(semctl(semid, 1, SETVAL, 1) == -1)
79 {
80 perror("semctl");
81 exit(1);
82 }
83 }
84
85 memset(addr, 0, 1024);
86 signal(SIGINT, sig_int);
87 pthread_t tid;
88 if(pthread_create(&tid, NULL, read_shm, NULL) == -1)
89 {
90 perror("pthread_create");
91 exit(1);
92 }
93 pthread_detach(tid);
94
95 while(1)
96 {
97 //
98 // printf
99 ret = read(0, addr->msg, 1020);
100 if(ret == -1)
101 {
102 perror("read");
103 continue;
104 }
105 addr->msg[ret] = '\0';
106 addr->type = 2;
107 semv(0);
108 }
109
110 return 0;
111 }
112
113 void semp(int p)
114 {
115 struct sembuf sops = { p, -1, 0};
116 if(semop(semi, &sops, 1) == -1)
117 {
118 if(errno == 22)
119 exit(0);
120 perror("semop_semp");
121 exit(1);
122 }
123 }
124 void semv(int p)
125 {
126 struct sembuf sops = { p, 1, 0};
127 if(semop(semid, &sops, 1) == -1)
128 {
129 if(errno == 22)
130 exit(0);
131 perror("semop_semv");
132 exit(1);
133 }
134 }
135
136 void *read_shm(void *arg)
137 {
138 while(1)
139 {
140 semp(1);
141 if(addr->type == 1)
142 {
143 printf("miki:%s", addr->msg);
144 addr->type = 0;
145 memset(addr, 0, 1024);
146 }
147 //sleep(1);//printf("isisisisis\n");
148 }
149 }
150
151 void sig_int(int sig)
152 {
153 if(shmdt(addr) == -1)
154 {
155 perror("shmdt");
156 exit(1);
157 }
158
159 if(shmctl(shmid, IPC_RMID, NULL) == -1)
160 {
161 perror("shmctl");
162 exit(1);
163 }
164
165 if(semctl(semid, 0, IPC_RMID) == -1)
166 {
167 perror("semctl");
168 exit(1);
169 }
170
171 exit(0);
172 }
阅读(218) | 评论(0) | 转发(0) |