用linux编写有P1,P2,P3三个进程,P1和P2负责从键盘接收字符串,均发送给P3,P3接收到字符串,根据发送方分别显示”P3 received *** from P1(或P2)" ;分别用管道通信,消息队列和共享存储三种通信方式实现。
时间: 2023-06-24 09:05:16 浏览: 90
以下是使用管道通信实现的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BUFFER_SIZE 1024
int main() {
int pipe1[2], pipe2[2], pid1, pid2;
char buffer[BUFFER_SIZE];
if (pipe(pipe1) == -1) {
perror("pipe1 failed");
exit(EXIT_FAILURE);
}
if (pipe(pipe2) == -1) {
perror("pipe2 failed");
exit(EXIT_FAILURE);
}
if ((pid1 = fork()) == -1) {
perror("fork pid1 failed");
exit(EXIT_FAILURE);
}
if (pid1 == 0) {
// Child Process P1
close(pipe1[0]);
close(pipe2[0]);
close(pipe2[1]);
while (1) {
printf("Enter a string (P1): ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strlen(buffer) - 1] = '\0'; // Remove newline character
write(pipe1[1], buffer, strlen(buffer) + 1);
}
close(pipe1[1]);
} else {
if ((pid2 = fork()) == -1) {
perror("fork pid2 failed");
exit(EXIT_FAILURE);
}
if (pid2 == 0) {
// Child Process P2
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
while (1) {
printf("Enter a string (P2): ");
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strlen(buffer) - 1] = '\0'; // Remove newline character
write(pipe2[1], buffer, strlen(buffer) + 1);
}
close(pipe2[1]);
} else {
// Parent Process P3
close(pipe1[1]);
close(pipe2[1]);
while (1) {
fd_set read_set;
FD_ZERO(&read_set);
FD_SET(pipe1[0], &read_set);
FD_SET(pipe2[0], &read_set);
select(FD_SETSIZE, &read_set, NULL, NULL, NULL);
if (FD_ISSET(pipe1[0], &read_set)) {
read(pipe1[0], buffer, BUFFER_SIZE);
printf("P3 received %s from P1\n", buffer);
}
if (FD_ISSET(pipe2[0], &read_set)) {
read(pipe2[0], buffer, BUFFER_SIZE);
printf("P3 received %s from P2\n", buffer);
}
}
close(pipe1[0]);
close(pipe2[0]);
}
}
return 0;
}
```
以下是使用消息队列实现的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFFER_SIZE 1024
struct message {
long type;
char text[BUFFER_SIZE];
};
int main() {
int msgid, pid1, pid2;
struct message msg;
key_t key = ftok(".", 'a');
if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) {
perror("msgget failed");
exit(EXIT_FAILURE);
}
if ((pid1 = fork()) == -1) {
perror("fork pid1 failed");
exit(EXIT_FAILURE);
}
if (pid1 == 0) {
// Child Process P1
while (1) {
printf("Enter a string (P1): ");
fgets(msg.text, BUFFER_SIZE, stdin);
msg.text[strlen(msg.text) - 1] = '\0'; // Remove newline character
msg.type = 1;
msgsnd(msgid, &msg, strlen(msg.text) + 1, 0);
}
} else {
if ((pid2 = fork()) == -1) {
perror("fork pid2 failed");
exit(EXIT_FAILURE);
}
if (pid2 == 0) {
// Child Process P2
while (1) {
printf("Enter a string (P2): ");
fgets(msg.text, BUFFER_SIZE, stdin);
msg.text[strlen(msg.text) - 1] = '\0'; // Remove newline character
msg.type = 2;
msgsnd(msgid, &msg, strlen(msg.text) + 1, 0);
}
} else {
// Parent Process P3
while (1) {
msgrcv(msgid, &msg, BUFFER_SIZE, 0, 0);
if (msg.type == 1) {
printf("P3 received %s from P1\n", msg.text);
} else if (msg.type == 2) {
printf("P3 received %s from P2\n", msg.text);
}
}
msgctl(msgid, IPC_RMID, NULL);
}
}
return 0;
}
```
以下是使用共享存储实现的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define BUFFER_SIZE 1024
struct shared_memory {
char text[BUFFER_SIZE];
};
int main() {
int shmid, pid1, pid2;
struct shared_memory *shm;
key_t key = ftok(".", 'a');
if ((shmid = shmget(key, sizeof(struct shared_memory), 0666 | IPC_CREAT)) == -1) {
perror("shmget failed");
exit(EXIT_FAILURE);
}
if ((shm = (struct shared_memory *) shmat(shmid, NULL, 0)) == (struct shared_memory *) -1) {
perror("shmat failed");
exit(EXIT_FAILURE);
}
if ((pid1 = fork()) == -1) {
perror("fork pid1 failed");
exit(EXIT_FAILURE);
}
if (pid1 == 0) {
// Child Process P1
while (1) {
printf("Enter a string (P1): ");
fgets(shm->text, BUFFER_SIZE, stdin);
shm->text[strlen(shm->text) - 1] = '\0'; // Remove newline character
printf("P1 wrote: %s\n", shm->text);
}
} else {
if ((pid2 = fork()) == -1) {
perror("fork pid2 failed");
exit(EXIT_FAILURE);
}
if (pid2 == 0) {
// Child Process P2
while (1) {
printf("Enter a string (P2): ");
fgets(shm->text, BUFFER_SIZE, stdin);
shm->text[strlen(shm->text) - 1] = '\0'; // Remove newline character
printf("P2 wrote: %s\n", shm->text);
}
} else {
// Parent Process P3
while (1) {
sleep(1); // Wait for P1 or P2 to write
if (strlen(shm->text) != 0) {
if (strstr(shm->text, "P1") != NULL) {
printf("P3 received %s from P1\n", shm->text);
} else if (strstr(shm->text, "P2") != NULL) {
printf("P3 received %s from P2\n", shm->text);
}
shm->text[0] = '\0'; // Clear shared memory
}
}
shmdt(shm);
shmctl(shmid, IPC_RMID, NULL);
}
}
return 0;
}
```
注意:由于共享内存是多个进程都可以访问的,因此在使用共享内存时需要注意同步和互斥问题,例如使用信号量等机制。上述代码简单地使用了 sleep 函数来等待 P1 或 P2 写入数据。
阅读全文