Fork()不创建子对象-C

Fork()不创建子对象-C,c,pipe,fork,C,Pipe,Fork,我在树莓皮3B上做一个操作系统项目。我必须用C语言实现一种进程管理程序。有一个主进程P,它必须处理进程链接列表P1-P2--P3-…PN。(这是一个过程链,意味着P1分叉P2,P2分叉P3等等)。列表以P1初始化,P1是P的子元素 在硬件级别上,分别有4个按钮(1、2、3、4)和4个LED,每对按钮由单个进程管理。这4个S进程也是主进程P的子进程,但不在链表中。现在,每个按钮都有一个在列表上执行的不同操作 按钮1删除列表中的第一个进程并移动所有进程 跟随前进一个位置。移动意味着 从n个进程中清

我在树莓皮3B上做一个操作系统项目。我必须用C语言实现一种进程管理程序。有一个主进程P,它必须处理进程链接列表P1-P2--P3-…PN。(这是一个过程链,意味着P1分叉P2P2分叉P3等等)。列表以P1初始化,P1是P的子元素

在硬件级别上,分别有4个按钮(1、2、3、4)和4个LED,每对按钮由单个进程管理。这4个S进程也是主进程P的子进程,但不在链表中。现在,每个按钮都有一个在列表上执行的不同操作

  • 按钮1删除列表中的第一个进程并移动所有进程 跟随前进一个位置。移动意味着 从n个进程中清空大小为n的列表,然后创建n-1 然后又加了回去,以这种方式模拟只删除第一个进程P1(它们确实是新进程)
  • 按钮2向列表中添加一个新流程PN+1
  • 按钮3选择列表中的下一个进程(当列表初始化时,P1默认为选中)
  • 按钮4从列表中删除所选进程(与按钮2相同,但仅移动列表末尾所选的部分)
我已经正确地实现了所有硬件部分,pS进程通过管道进行通信,因此这超出了本问题的范围。我还设法实现了按钮2和3,以便它们满足要求

关于如何实现按钮1,我已经被困了一个多星期了

这是主菜单

任务管理器现在只显示主进程p和四个S进程。 经过大量检查,我发现M_process.c中initialize_list()函数中的分叉不起作用。主进程从fork()接收一个新的pid,实际上pid被添加到列表中(在输出示例中为30619),但实际上没有具有该pid的现有进程。它甚至不会被创建并立即退出,因为我试图在pid==0分支中放入一条print语句,但什么也没有发生。当列表中只有一个元素P1时(另一件我自己无法解释的事情),它确实能按预期工作

我真的不明白为什么fork()调用会将一个pid返回到主进程p,但实际上不会用该pid创建子进程,这似乎是阻止我继续进行项目的问题


(我意识到这一切都有点混乱,可能不太清楚,但我发现很难总结我需要完成的任务和我的现状。此外,我意识到我发布这个问题的方式不允许你测试它,但由于同时处理硬件部分,我认为它会变得更加复杂。)在安装信号处理程序之前,
initialize\u列表中的
fork
确实创建了一个新的进程,但是在
add\u进程中的
kill
会立即终止它

您可以在
fork
之前阻止信号,然后在安装信号处理程序后和在父级中取消阻止它,或者在调用
fork
之前只安装信号处理程序

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/wait.h>
#include "linkedlist.h"
#include "M_process.h"
#include "S_process.h"

int main(int argc, char *argv[]) {
    const char BUTTONS[] = "FASD";
    const int N_OF_S = 4;
    int fd1[2], fd2[2];  // pipes (P to S) and (S to P) 
    pid_t s_processes[N_OF_S];
    int arg_index = 1;
    setup_pipes(fd1, fd2);

    pid_t pid;
    for (int i = 0; i < N_OF_S; i++) {
        pid = fork();
        if (pid < 0) {
            fprintf(stderr, "Error in forking process S%d\n", i);
            return -1;
        } else if (pid > 0) {
            arg_index += 2;
            s_processes[i] = pid;
        } else {
            close(fd1[1]);
            close(fd2[0]);
            char *p;
            long button, led;
            button = strtol(argv[arg_index], &p, 10);
            led = strtol(argv[arg_index + 1], &p, 10);
            s_fun((int) button, (int) led, BUTTONS[i], fd1, fd2);
            return 0;
        }
    }
    close(fd1[0]);
    close(fd2[1]);

    List list;
    List *p_list = &list;
    initialize_list(p_list);

    pthread_t t;
    pthread_create(&t, NULL, listen_input, p_list);

    process_buttons(p_list);

    for (int i = 0; i < N_OF_S; i++) {
        waitpid(s_processes[i], NULL, 0);
    }

    wait(NULL);

    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include "linkedlist.h"
#include "P_process.h"

int m_to_s[2];
int s_to_m[2];
int p_to_m[2];

void initialize_list(List *list) {
    int fd[2];
    pipe(fd);
    p_to_m[1] = fd[1];
    p_to_m[0] = fd[0];
    init_list(list);
    pid_t pid = fork();
    if (pid < 0) {
        fprintf(stderr, "Couldn't fork\n");
    } else if (pid == 0) {
        close(m_to_s[1]);
        close(s_to_m[0]);
        close(fd[0]);
        signal(SIGINT, term_handler);
        signal(SIGUSR1, fork_handler);
        p_listen(1, fd);
        close(fd[1]);
        exit(0);
    } else {
        close(fd[1]);
        append(list, pid, "00000000");
    }
}

void *listen_input(void *list) {
    char input;
    int reading = 1;
    while (reading) {
        scanf(" %c", &input);
        switch (input) {
            case 'q':
                reading = 0;
                for (int i = 0; i < 4; i++) {
                    write(m_to_s[1], &input, sizeof(char));
                }
                for (int i = size(list); i > 0; i--) {
                    kill(last_pid(list), SIGINT);
                    remove_last(list);
                }
                fprintf(stderr, "List deallocated.\n");
                break;
            case 'p':
                print_list(list);
                break;
            case 'h':
                fprintf(stderr, "Enter '\e[1;37mp\e[0m' to inspect the list or '\e[1;37mq\e[0m' to exit.\n");
                break;
            default:
                fprintf(stderr, "Command not found.\n");
                break;
        }
    }
    fprintf(stderr, "Goodbye!\n");
    pthread_exit(NULL);
}

int setup_pipes(int fd1[2], int fd2[2]) {
    if (pipe(fd1) < 0 || pipe(fd2) < 0) {
        fprintf(stderr, "Error in creating pipes\n");
        return -1;
    }
    m_to_s[1] = fd1[1];
    s_to_m[0] = fd2[0];
    return 0;
}

pid_t add_process(List *list, int n_of_processes) {
    if (n_of_processes > 0) {
        kill(last_pid(list), SIGUSR1);
        pid_t pid;
        read(p_to_m[0], &pid, sizeof(pid_t));
        char *p;
        p = id_generator(8);
        append(list, pid, p);
        add_process(list, n_of_processes - 1);
        return pid;
    }
    return 0;
}

void process_buttons(List *list) {
    char cmd;
    while (read(s_to_m[0], &cmd, sizeof(char)) != 0) {
        switch (cmd) {
            case 'F': {
                pid_t removed = first_pid(list);
                int to_add = size(list) - 1;
                for (int i = size(list); i > 0; i--) {
                    kill(last_pid(list), SIGINT);
                    remove_last(list);
                }
                initialize_list(list);
                add_process(list,to_add);
                fprintf(stderr, "(\e[1;31m-\e[0m) First process (\e[1;37m%d\e[0m) removed.\n", removed);
                break;
            }
            case 'A': {
                pid_t pid = add_process(list, 1);
                fprintf(stderr, "(\e[1;32m+\e[0m) Process \e[1;37m%d\e[0m [id: %s] appended to the list.\n", pid,
                        last_id(list));
                break;
            }
            case 'S': {
                select_next(list);
                fprintf(stderr, "(\e[1;33m*\e[0m) Next process (\e[1;37m%d\e[0m) selected.\n", selected_pid(list));
                break;
            }
            case 'D': {
                fprintf(stderr, "(\e[1;31m-\e[0m) Removed selected process (\e[1;37m%d\e[0m) from the list.\e[0m\n",
                        selected_pid(list));
                break;
            }
            default: {
                break;
            }
        }
    }
}
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int fd[2];
int listen;

void p_listen(int l, int fd3[2]) {
    fd[0] = fd3[0];
    fd[1] = fd3[1];
    listen = l;
    while (listen) pause();
}

void fork_handler(int signo) {
    pid_t pid = fork();
    if (pid < 0) {
        fprintf(stderr, "Couldn't add another P");
    } else if (pid > 0) {
        write(fd[1], &pid, sizeof(pid_t));
    }
}

void term_handler(int signo) {
    listen = 0;
}
p
Process list: 30594
(+) Process 30611 [id:pkDHTxmM] appended to the list.
(+) Process 30612 [id:R18N2l9k] appended to the list.      // Pressed four times
(+) Process 30615 [id:88EmLgN7] appended to the list.      // button 2
(+) Process 30616 [id:cCCTt9rW] appended to the list.
p
Process list: 30594 -> 30611 -> 30612 -> 30615 -> 30616
(-) First process (30594) removed.                         // Pressed once first button
p
Process list: 30619 -> 7 -> 6370080 -> 6370120