0

I'm trying to create a piped multithreaded, multiprocess program where the parent process will create a thread that will read from a pipe from a sending child and then write to another pipe to the target child. But when the sending child process invokes piped write() to the parent process, the parent process won't read; it continues to block.

Pipe creation and the parent process creating the thread

int value1 = pipe(to_parent[index]);
int value2 = pipe(from_parent[index]);

if(value1 == -1) {
    perror("pipe");
    continue;
}

if(value2 == -1) {
    perror("pipe");
    continue;
}   
/* fork for every connection to the server*/
int pid = fork();


/*go back to the beginning of loop if fork fails*/
if(pid == -1) {
    perror("fork failed");
    continue;
}

/* parent process will go back to the beginning of the loop */
if(pid != 0) {
    close(from_parent[index][0]);
    close(to_parent[index][1]);
    pthread_create(&parent_listen_to_child[index], NULL, listen_to_child, &index);
    continue;
}


/*PIPE
  CHILD => PARENT*/
void * listen_to_child(void * ptr) {
    int index = *(int*)ptr;
    int index_to_kill;
    printf("listen_to_child\n");
    read(to_parent[index][0], &index_to_kill, sizeof(int));
    printf("talk to child\n");
    write(from_parent[index_to_kill][1], &index, sizeof(int));
}

Child processes create the thread that reads from parent through pipe and a thread which would soon write to the parent through the pipe

void respond(int index) {
    char buffer[MAX];
    int client_socket = clients[index].socket;
    char name[MAX_NAME_SIZE];
    strcpy(name, get_name(client_socket));
    strcpy(clients[index].name, name);
    
    printf("%s has connected to the server\n", name);
    print_names();
    printf("hello\n");
    

    pthread_create(&command_processor, NULL, receive_command, &index);
    
    /* close pipe ends in child*/
    close(from_parent[index][1]);
    close(to_parent[index][0]);
    pthread_create(&child_listen_to_parent, NULL, listen_to_parent, &index);
    
    pthread_join(child_listen_to_parent, NULL);
    pthread_join(command_processor, NULL);
}

/* PIPE
   PARENT => CHILD TO CANCEL*/
void * listen_to_parent(void * ptr) {
    int index = *(int*)ptr;
    int tattle;
    printf("listen_to_parent\n");
    read(from_parent[index][0], &tattle, sizeof(int));
    printf("cancel %s\n", clients[index].name);
    pthread_cancel(command_processor);
}

Where the write to the parent process from sending child is invoked

void send_talk(client sender, client target) {
    printf("sender: %s\ntarget: %s\n", sender.name, target.name);
    
    int sender_index = get_index(sender.socket);
    int target_index = get_index(target.socket);
    
    int write_value;
    
    if(( write_value = write(to_parent[sender_index][1], &target_index, sizeof(int))) != -1) {
        printf("write successful: wrote %d bytes\n", write_value);
    }
    else {
        printf("write unsuccessful\n");
    }
}
  • Without studying your code, just in case any of this is useful: [here is a great and simple pipe demo](https://stackoverflow.com/a/28971647/4561887). – Gabriel Staples Apr 05 '22 at 19:14
  • At a glance, you're using both `fork` and `pthread_create`. You can probably just use `fork` – Craig Estey Apr 05 '22 at 20:06

0 Answers0