为了账号安全,请及时绑定邮箱和手机立即绑定

作业社区

探索学习新天地,共享知识资源!

0 提交作业
0 布置作业
0 满分作业
得分 100
学习任务

jelasin 的学生作业:

//time_server.c #include #include #include #include #include #include #include #include #include #include #define FIFO_NAME "/tmp/time_fifo" void cleanup() { unlink(FIFO_NAME); } void signal_handler(int signum) { exit(EXIT_SUCCESS); } int main() { int fd; char buffer[128]; time_t currentTime; if (access(FIFO_NAME, F_OK) == -1) { if (mkfifo(FIFO_NAME, 0666) != 0) { perror("mkfifo"); exit(EXIT_FAILURE); } } atexit(cleanup); if (signal(SIGINT, signal_handler) == SIG_ERR) { perror("signal"); exit(EXIT_FAILURE); } if (signal(SIGTERM, signal_handler) == SIG_ERR) { perror("signal"); exit(EXIT_FAILURE); } if (signal(SIGPIPE, signal_handler) == SIG_ERR) { perror("signal"); exit(EXIT_FAILURE); } fd = open(FIFO_NAME, O_WRONLY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } while (true) { currentTime = time(NULL); if (currentTime == ((time_t)-1)) { perror("time"); exit(EXIT_FAILURE); } snprintf(buffer, sizeof(buffer), "%s", ctime(&currentTime)); if (write(fd, buffer, strlen(buffer) + 1) == -1) { perror("write"); exit(EXIT_FAILURE); } sleep(1); } close(fd); return 0; } #include #include #include #include #include #define FIFO_NAME "/tmp/time_fifo" int main() { int fd; char buffer[128]; fd = open(FIFO_NAME, O_RDONLY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } while (true) { if (read(fd, buffer, sizeof(buffer)) > 0) { printf("Current time: %s", buffer); } else { perror("read"); exit(EXIT_FAILURE); } } close(fd); return 0; } 【图片】

得分 100
学习任务

jelasin 的学生作业:

#include #include #include #include #include #include #include #include #include #define SZ_CMDLINE 0x100 #define SZ_ARGS 0x40 typedef struct cmdline { char cmd[SZ_CMDLINE]; char *args[SZ_ARGS]; } cmd_t; int r_wait(int *status) { int ret_val; while ((ret_val = wait(status)) == -1 && errno == EINTR); return ret_val; } int exec_handler(const cmd_t* cmd) { pid_t pid; int status; if ((pid = fork()) cmd, cmd->args) cmd, token, SZ_CMDLINE); #if defined(DEBUG) printf("cmd->cmd: %s\n", cmd->cmd); #endif int i = 0; while (token != NULL) { token = strtok_r(NULL, " ", &saveptr); if (token == NULL) { break; } cmd->args[i] = malloc(SZ_CMDLINE); strncpy(cmd->args[i], token, SZ_CMDLINE); #if defined(DEBUG) printf("cmd->args[%d]: %s\n", i, cmd->args[i]); #endif if (++i == SZ_ARGS) { perror("[WARNING ==> function parse_cmdline] too many args"); break; } } cmd->args[i] = NULL; #if defined(DEBUG) printf("cmd->cmd: %s\n", cmd->cmd); for (int j = 0; cmd->args[j]; j++) { printf("cmd->args[%d]: %s\n", j, cmd->args[j]); } #endif return 0; } int main() { cmd_t cmd; char *cmdline = malloc(SZ_CMDLINE); while (true) { memset(cmdline, '\0', SZ_CMDLINE); memset(&cmd, '\0', sizeof(cmd_t)); fprintf(stderr, "minishell-> "); fgets(cmdline, SZ_CMDLINE, stdin); cmdline[strcspn(cmdline, "\n")] = '\0'; if (strcmp(cmdline, "exit") == 0) { free(cmdline); cmdline = NULL; for (int i = 0; cmd.args[i]; i++) { free(cmd.args[i]); cmd.args[i] = NULL; } break; } parse_cmdline(cmdline, &cmd); exec_handler(&cmd); for (int i = 0; cmd.args[i]; i++) { free(cmd.args[i]); cmd.args[i] = NULL; } } return 0; }

得分 100
学习任务

jelasin 的学生作业:

从内核2.6.32开始,在默认情况下,父进程将成为fork之后优先调度的对象。采取这种策略的原因是:fork之后,父进程在CPU中处于活跃的状态,并且其内存管理信息也被置于硬件内存管理单元的转译后备缓冲器(TLB),所以先调度父进程能提升性能。 从2.6.24起,Linux采用完全公平调度(Completely Fair Scheduler,CFS)。用户创建的普通进程,都采用CFS调度策略。对于CFS调度策略,procfs提供了如下控制选项:/proc/sys/kernel/sched_child_runs_first 该值默认是0,表示父进程优先获得调度。如果将该值改成1,那么子进程会优先获得调度。 POSIX标准和Linux都没有保证会优先调度父进程。因此在应用中,决不能对父子进程的执行顺序做任何的假设。如果确实需要某一特定执行的顺序,那么需要使用进程间同步的手段。 从 Linux 内核版本 5.9 开始,kernel.sched_child_runs_first 参数被移除了。在移除该参数后,内核默认的行为是父进程在 fork() 后优先运行,并且无法通过参数进行更改。 // main.c #include #include #include int global_var = 0; int main() { pid_t pid = fork(); if (pid == 0) { global_var = 100; printf("Child process: global_var = %d\n", global_var); } else { printf("Parent process: global_var = %d\n", global_var); } return 0; } ---------------------------------------------------------------------- ➜ 5 ./main Parent process: global_var = 0 Child process: global_var = 100 ➜ 5 ./main Parent process: global_var = 0 Child process: global_var = 100 ➜ 5 ./main Parent process: global_var = 0 Child process: global_var = 100 ➜ 5 ./main Parent process: global_var = 0 Child process: global_var = 100 ➜ 5 ./main Parent process: global_var = 0 Child process: global_var = 100 ➜ 5 ./main Parent process: global_var = 0 Child process: global_var = 100 // main.c #include #include #include #include int global_var = 0; int main() { pid_t pid = fork(); if (pid == 0) { global_var = 100; printf("Child process: global_var = %p==>%d\n", &global_var, global_var); } else { waitpid(pid, NULL, 0); printf("Parent process: global_var = %p==>%d\n", &global_var, global_var); } return 0; } ---------------------------------------------------------------- ➜ 5 clang main.c -o main ➜ 5 ./main Child process: global_var = 0x64df76b22044==>100 Parent process: global_var = 0x64df76b22044==>0 Linux 采用写时复制技术,现在大部分的Linux中fork也采用了vfork的技术,读取时不会进行内存空间的拷贝,只有子进程在向某处可写地址写入时才会进行拷贝复制,子进程复制父进程被写入的那段内存。且仅在子进程地址空间生效,父子进程采用独立的地址空间。

微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号