C - 在进程之间来回发送数据
C - Sending data back and forth between processes
我正在研究下面的程序。它应该做的是从子进程获取随机整数,并根据 item_count 变量,return 通过使用管道向子进程发送适当的消息。问题是我在执行时遇到了很多意想不到的行为,见下文。 myCatalog 是一个结构。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/wait.h>
#include <string.h>
struct catalog {
char description[128];
int price;
int item_count;
};
int main() {
int i, j, k, fd1[5][2], fd2[5][2];
struct catalog myCatalog[3];
pid_t pid;
int itemNo;
char message[24];
char messageFailure[] = "Failure.", messageSuccess[] = "Success!";;
for(i = 0; i < 5; i++) {
if(pipe(fd1[i]) == -1) {
printf("Error opening pipe 1!\n");
exit(1);
}
if(pipe(fd2[i]) == -1) {
printf("Error opening pipe 2!\n");
exit(1);
}
pid = fork();
if(pid == 0) { //Child
time_t t;
srand((int)time(&t) % getpid());
close(fd1[i][0]); //Close reading end of fd1
close(fd2[i][1]); //Close writing end of fd2
for(k = 0; k < 10; k++) {
itemNo = rand() % 21;
write(fd1[i][1], &itemNo, sizeof(int));
sleep(1);
read(fd2[i][0], message, sizeof(message));
printf("%s\n", message);
}
printf("Hello from child process %d\n", getpid());
close(fd1[i][1]);
close(fd2[i][0]);
exit(0);
}
else if(pid > 0) { //Parent
int item;
close(fd1[i][1]); //Close writing end of fd1
close(fd2[i][0]); //Close reading end of fd2
if(i == 0) {
for(j = 0; j < 20; j++) {
snprintf(myCatalog[j].description, sizeof(myCatalog[j].description), "Item #%d", j);
myCatalog[j].price = (rand() % 10) + 1;
myCatalog[j].item_count = 2;
}
for(j = 0; j < 20; j++) {
printf("Description: %s\n", myCatalog[j].description);
printf("Price: %d\n", myCatalog[j].price);
printf("Count: %d\n", myCatalog[j].item_count);
}
}
for(j = 0; j < 10; j++) {
read(fd1[i][0], &item, sizeof(int));
printf("%d\n", item);
myCatalog[item].item_count = myCatalog[item].item_count - 1;
if(myCatalog[item].item_count <= 0) {
write(fd2[i][1], messageFailure, sizeof(messageFailure));
}
else {
write(fd2[i][1], messageSuccess, sizeof(messageSuccess));
}
sleep(1);
}
printf("Hello from parent process %d\n", getpid());
close(fd1[i][0]);
close(fd2[i][1]);
wait(NULL);
}
else {
printf("Error forking!");
exit(1);
}
}
return 0;
}
一个子进程的示例输出如下所示:
Hello from parent process 11868
Hello from child process 11890
6
Success!
4
Success!
3
Success!
4
3
16
Success!
14
3
6
3
18
3
20
3
18
3
它应该做的是打印数字,然后是成功或失败等等。另外,它有时会输出 13 个数字而不是 10 个。问题是,问题在哪里?是我的管道吗?我的循环使用完全错误吗?
任何帮助将不胜感激。
这看起来肯定不对。为 n > 2 访问 myCatalog[n]
会调用未定义的行为。
struct catalog myCatalog[3];
...
for(j = 0; j < 20; j++) {
printf("Description: %s\n", myCatalog[j].description);
我正在研究下面的程序。它应该做的是从子进程获取随机整数,并根据 item_count 变量,return 通过使用管道向子进程发送适当的消息。问题是我在执行时遇到了很多意想不到的行为,见下文。 myCatalog 是一个结构。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/wait.h>
#include <string.h>
struct catalog {
char description[128];
int price;
int item_count;
};
int main() {
int i, j, k, fd1[5][2], fd2[5][2];
struct catalog myCatalog[3];
pid_t pid;
int itemNo;
char message[24];
char messageFailure[] = "Failure.", messageSuccess[] = "Success!";;
for(i = 0; i < 5; i++) {
if(pipe(fd1[i]) == -1) {
printf("Error opening pipe 1!\n");
exit(1);
}
if(pipe(fd2[i]) == -1) {
printf("Error opening pipe 2!\n");
exit(1);
}
pid = fork();
if(pid == 0) { //Child
time_t t;
srand((int)time(&t) % getpid());
close(fd1[i][0]); //Close reading end of fd1
close(fd2[i][1]); //Close writing end of fd2
for(k = 0; k < 10; k++) {
itemNo = rand() % 21;
write(fd1[i][1], &itemNo, sizeof(int));
sleep(1);
read(fd2[i][0], message, sizeof(message));
printf("%s\n", message);
}
printf("Hello from child process %d\n", getpid());
close(fd1[i][1]);
close(fd2[i][0]);
exit(0);
}
else if(pid > 0) { //Parent
int item;
close(fd1[i][1]); //Close writing end of fd1
close(fd2[i][0]); //Close reading end of fd2
if(i == 0) {
for(j = 0; j < 20; j++) {
snprintf(myCatalog[j].description, sizeof(myCatalog[j].description), "Item #%d", j);
myCatalog[j].price = (rand() % 10) + 1;
myCatalog[j].item_count = 2;
}
for(j = 0; j < 20; j++) {
printf("Description: %s\n", myCatalog[j].description);
printf("Price: %d\n", myCatalog[j].price);
printf("Count: %d\n", myCatalog[j].item_count);
}
}
for(j = 0; j < 10; j++) {
read(fd1[i][0], &item, sizeof(int));
printf("%d\n", item);
myCatalog[item].item_count = myCatalog[item].item_count - 1;
if(myCatalog[item].item_count <= 0) {
write(fd2[i][1], messageFailure, sizeof(messageFailure));
}
else {
write(fd2[i][1], messageSuccess, sizeof(messageSuccess));
}
sleep(1);
}
printf("Hello from parent process %d\n", getpid());
close(fd1[i][0]);
close(fd2[i][1]);
wait(NULL);
}
else {
printf("Error forking!");
exit(1);
}
}
return 0;
}
一个子进程的示例输出如下所示:
Hello from parent process 11868
Hello from child process 11890
6
Success!
4
Success!
3
Success!
4
3
16
Success!
14
3
6
3
18
3
20
3
18
3
它应该做的是打印数字,然后是成功或失败等等。另外,它有时会输出 13 个数字而不是 10 个。问题是,问题在哪里?是我的管道吗?我的循环使用完全错误吗? 任何帮助将不胜感激。
这看起来肯定不对。为 n > 2 访问 myCatalog[n]
会调用未定义的行为。
struct catalog myCatalog[3];
...
for(j = 0; j < 20; j++) {
printf("Description: %s\n", myCatalog[j].description);