我的代码有问题。我想在两个孩子之间进行沟通。其中一个是服务器,它打开一个文件并将每个字母发送到第二个进程。第二个过程是计算字母,它应该制作一个新文件并保存结果。我对最后一步有问题,因为第一个过程比第二个过程完成得更快,这导致程序结束。我不知道如何解决。寻找一些技巧:)。
您在这里得到结果。
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
//stale
#define FIFO "my_fifo"
#define SIZE 26
//zmienne globalne
int desk; //deskryptor pliku
int tab[SIZE];
//prototypy funkcji
void parentKillAll();
void server(FILE * file);
void client();
void cleanUp(FILE * file);
int checkEntryData(int argc, char *argv);
void replaceTabWithZero(int * tab);
void countLetters(int * tab, char ch);
void saveResults(int * tab, char *title);
void showTab(int * tab);
int main(int argc, char *argv[]) {
if (!checkEntryData(argc, argv[1]))
return 1;
replaceTabWithZero(tab);
FILE *file = fopen(argv[1], "r");
umask(0);
mkfifo(FIFO, 0666);
if (file) {
if (fork() == 0) {
server(file);
exit(0);
} else if (fork() == 0) {
client();
saveResults(tab, strcat(argv[1], "Result"));
showTab(tab);
exit(0);
} else {
cleanUp(file);
parentKillAll();
}
} else {
perror("Error");
}
return 0;
}
void parentKillAll() {
sleep(1);
kill(0, SIGKILL);
exit(0);
}
void server(FILE * file) {
char ch;
while ((ch = fgetc(file)) != EOF) {
desk = open(FIFO, O_WRONLY);
write(desk, &ch, 1);
}
}
void client() {
char ch;
while (1) {
desk = open(FIFO, O_RDONLY);
read(desk, &ch, 1);
countLetters(tab, ch);
printf("%c", ch);
}
}
void cleanUp(FILE *file) {
wait(0);
fclose(file);
close(desk);
}
int checkEntryData(int argc, char *argv) {
if (argc < 2) {
fprintf(stderr, "Nie poprawna ilosc argumentow\n");
return 0;
}
if (access(argv, F_OK)) {
fprintf(stderr, "Podany plik \'%s\' nie istnieje\n", argv);
return 0;
}
if (access(argv, R_OK)) {
fprintf(stderr, "Brak uprawnien do odczytu pliku \'%s\'\n", argv);
return 0;
}
return 1;
}
void replaceTabWithZero(int * tab) {
for (int i = 0; i < SIZE; i++)
tab[i] = 0;
}
void countLetters(int *tab, char ch) {
int chVal = ch;
if (chVal > 92)
chVal -= 32;
if (chVal > 64 && chVal < 91)
tab[chVal-65] += 1;
}
void saveResults(int *tab, char * title) {
FILE *plik = fopen(title, "w");
if (plik) {
for (int i = 0; i < SIZE; i++)
fprintf(plik, "%c - %d\n", (i+97), tab[i]);
} else {
perror("Error");
}
fclose(plik);
}
void showTab(int * tab) {
for (int i = 0; i < SIZE; i++)
printf("\n%d", tab[i]);
}
答案 0 :(得分:0)
真正的问题是客户端进程永远无法完成,因为它运行了无限的while(1)
循环而没有任何退出条件。
您应该重写它,以使其在读取所有可用数据后退出:
void client() {
char ch;
// Open the fifo only once, instead of once per character
desk = open(FIFO, O_RDONLY);
// Loop until there is no more data to read
while(read(desk, &ch, 1) > 0) {
countLetters(tab, ch);
printf("%c", ch);
}
}
从技术上讲,这足以使其起作用,但您还应该研究一系列其他问题:
wait(0)
调用,以便您等待两个进程,并且不应尝试杀死任何东西。fgetc
的输出与EOF 比较,然后再将值强制为char。由于这样做之后,在ISO-8859-1终端上运行程序将导致其混淆EOF和字母ÿ
strcat
上使用argv[1]
。您应该使用自己的已知长度的缓冲区。access
进行检查,然后假设一切正常,因为通话可能由于其他原因而失败,因此效果不佳。read
/ write
时,最好使用较大的缓冲区(例如65536字节而不是1)。 fgetc
之类的stdio函数已经在后台使用了更大的缓冲区。