[英]Unnamed Pipes in UNIX child message doesn't get received by father while sending a string in C
我用两个未命名的管道创建了两个进程,但是我无法弄清楚为什么我不能从儿子向父亲发送消息。 父亲似乎没有收到字符串。 儿子正在发送正确的字符串。 它只是没有到达目的地,不知道为什么...你能告诉我吗?
#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);
}
问题是这一行:
read(channel[i][0],string_lida,strlen(string_lida));
由于您未初始化string_lida
,因此strlen
可能会返回任何内容,但是我猜想它会返回0(字符串为空),因此您从不读取任何内容。 您要使用sizeof(string_lida)
。 然后,您需要手动NUL终止string_lida
的字符串,因为读取操作不会这样做。 因此,您需要检查read
的返回值以查看read
了多少个字符(或者它是否是EOF)。
您还只等待总共读取n_childs个字符串-如果每个孩子都发送多个字符串,则不会得到大多数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.