Fork()不创建子对象-C
我在树莓皮3B上做一个操作系统项目。我必须用C语言实现一种进程管理程序。有一个主进程P,它必须处理进程链接列表P1-P2--P3-…PN。(这是一个过程链,意味着P1分叉P2,P2分叉P3等等)。列表以P1初始化,P1是P的子元素 在硬件级别上,分别有4个按钮(1、2、3、4)和4个LED,每对按钮由单个进程管理。这4个S进程也是主进程P的子进程,但不在链表中。现在,每个按钮都有一个在列表上执行的不同操作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个进程中清
- 按钮1删除列表中的第一个进程并移动所有进程 跟随前进一个位置。移动意味着 从n个进程中清空大小为n的列表,然后创建n-1 然后又加了回去,以这种方式模拟只删除第一个进程P1(它们确实是新进程)
- 按钮2向列表中添加一个新流程PN+1
- 按钮3选择列表中的下一个进程(当列表初始化时,P1默认为选中)
- 按钮4从列表中删除所选进程(与按钮2相同,但仅移动列表末尾所选的部分)
(我意识到这一切都有点混乱,可能不太清楚,但我发现很难总结我需要完成的任务和我的现状。此外,我意识到我发布这个问题的方式不允许你测试它,但由于同时处理硬件部分,我认为它会变得更加复杂。)在安装信号处理程序之前,
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