[英]Unnamed Pipes in UNIX child message doesn't get received by father while sending a string in C
I have two processes that I have created with two unnamed pipes, but I can't figure out why I can't send messages from the sons to the father. 我用两个未命名的管道创建了两个进程,但是我无法弄清楚为什么我不能从儿子向父亲发送消息。 It appears that the father doesn't receive the string.
父亲似乎没有收到字符串。 The son is sending the right string;
儿子正在发送正确的字符串。 it just doesn't reach destination, can't figure out why ... Can you explain to me?
它只是没有到达目的地,不知道为什么...你能告诉我吗?
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <strings.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#define max_chars_string 1000
#define n_childs 2
pid_t childs[n_childs];
int channel[n_childs][2];
void read_lines(char * filename, char (*pointer)[max_chars_string],int init_read,int n_lines);
void get_strings_hash(char (*pointer_strings)[max_chars_string],char (*pointer_hashes)[max_chars_string],int total_lines);
void worker(int mypipe,char filename[],int n_lines){ // meter as funcoes de ler passwords no filho
int resources[2];// numero de linhas que cada processo tem de ler
int i = 0;
//definicao arrays
char strings_hashes[n_lines][max_chars_string];//aray de string com as strings lidas do ficheiro
char * pointer_strings = &strings_hashes[0][0];//ponteiro para o inicio do array das hashes
read_lines(filename,strings_hashes,0,n_lines); // le as strings do ficheiro e passa para o array
for(i = 0;i<n_lines;i++){
printf("%s \n",strings_hashes[i]);
}
printf("[%d] My parent is: %d\n", getpid(), getppid());
//open pipe to write and close pipe to read
close(channel[mypipe][0]);
i = 0;
int incr = 0;
while (i<n_lines) {
printf("[Son] Password sent e %s: \n",strings_hashes[incr]);
write(channel[mypipe][1], strings_hashes[incr], strlen(strings_hashes[incr]));
incr++;
i++;
}
exit(0);
}
int main(int argc, char **argv)
{
char *filename;
int status;//status do processos filho
int resources[2];// numero de linhas que cada processo tem de ler
int n_lines; //numero de linhas do ficheiro
int i = 0;
// Create a pipe
filename = (char*)malloc(strlen(argv[1])*sizeof(char)+1);
if(argc !=3){
fprintf(stderr, "Usage : %s [text_file] [cores]",argv[0]);
exit(0);
}
strcpy(filename,argv[1]);
char get_file [strlen(filename)];
strcpy(get_file,filename);
// start the processes
for(i = 0; i <atoi(argv[2]);i++){
pipe(channel[i]);
childs[i] = fork();
if(childs[i] == -1){
perror("Failed to fork");
return 1;
}
if (childs[i] == 0)
{
worker(i,get_file,n_lines);
}
close(channel[i][1]);
}
i = 0;
int k = 0;
int fd;
fd_set read_set;
FD_ZERO(&read_set);
char string_lida [30];
// working father
printf("[%d] I'm the father!\n", getpid());
printf("[Father]orking ...\n");
//unammed_pipes connection
while(k<n_childs){
FD_SET(channel[0][0], &read_set);
for(i=0;i<n_childs;i++){
FD_SET(channel[i][0], &read_set);
if(fd<channel[i][0]){ fd=channel[i][0];
}
}
if(select(fd+1,&read_set,NULL,NULL,NULL)>0){
for(i=0;i<n_childs;i++){
if(FD_ISSET(channel[i][0], &read_set)){
read(channel[i][0],string_lida,strlen(string_lida));
printf("[Father]pipe %d - string lida:%s\n",i,string_lida);
k++;
}
}
}
fd=1;
}
//
//waiting for childs ...
for(i=0;i<n_childs;i++){
wait(&status);
printf("waiting for childs \n");
}
return 0;
}
void get_strings_hash(char (*pointer_strings)[max_chars_string],char (*pointer_hashes)[max_chars_string],int total_lines)//vai ao array de strings e corta a parte de hash e mete num array
{
int i = 0;
char *strings;
char *hash;
for(i = 0;i<total_lines;i++){
strings = (char*)malloc(strlen(pointer_strings)*sizeof(char)+1);
strcpy(strings,*pointer_strings);
hash = (char*)malloc(strlen(pointer_strings)*sizeof(char)+1);
find_hash(strings,hash);
strcpy(*pointer_hashes,hash);
pointer_hashes++;
pointer_strings++;
}
}
void read_lines(char * filename, char (*pointer)[max_chars_string],int init_read,int n_lines){
FILE *fp;
char str[max_chars_string];
int i =0;
if((fp = fopen(filename, "r"))==NULL) {
printf("Cannot open file.\n");
exit(1);
}
if(init_read>0 && init_read<=n_lines){
for(i = 0;i<init_read;i++){
fgets(str, sizeof str, fp);
for(i = init_read;i<n_lines;i++){
fgets(str, sizeof str, fp);
strcpy(*pointer, str); //copia para a posicao actula do ponteiro
pointer++;
}
}
}
if(init_read<=n_lines && init_read==0){
for(i = init_read;i<n_lines;i++){
fgets(str, sizeof str, fp);
strcpy(*pointer, str); //copia para a posicao actula do ponteiro
pointer++;
}
}
fclose(fp);
}
One problem is this line: 问题是这一行:
read(channel[i][0],string_lida,strlen(string_lida));
since you don't initialize string_lida
, the strlen
might return anything, but I'm guessing its returning 0 (the string is empty), so you never read anything. 由于您未初始化
string_lida
,因此strlen
可能会返回任何内容,但是我猜想它会返回0(字符串为空),因此您从不读取任何内容。 You want sizeof(string_lida)
instead. 您要使用
sizeof(string_lida)
。 You then need to manually NUL-terminate the string in string_lida
as the read won't do so. 然后,您需要手动NUL终止
string_lida
的字符串,因为读取操作不会这样做。 So you need to check the return value of read
to see how many characters were read (or if it was an EOF). 因此,您需要检查
read
的返回值以查看read
了多少个字符(或者它是否是EOF)。
You also only wait for a total of n_childs strings to be read -- if each child sends more than one string, you won't get most of them. 您还只等待总共读取n_childs个字符串-如果每个孩子都发送多个字符串,则不会得到大多数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.