SIGKILL/SIGSTOP/SIGTSTP

本文详细介绍了SIGKILL和SIGSTOP两个信号的区别。SIGKILL用于彻底终止进程,而SIGSTOP则用于暂停进程执行但不终止。此外还解释了SIGTSTP的作用及与SIGSTOP的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SIGKILL/SIGSTOP/SIGTSTP



SIGKILL和SIGSTOP的区别

SIGKILL提供给管理员杀死进程的权利, SIGSTOP提供给管理员暂停进程的权利,所以这两个信号不能被忽略和重定义。

Kill父进程后, 子进程的父进程号为1; 但是stop父进程后子进程的父进程号还是该父进程。

 

 

SIGSTOP和SIGTSTP的区别

SIGSTOP提供给管理员暂停进程的特权, 所以不能忽略和重定义。

当用户按下CTRL-Z时, 向前台进程组发送SIGTSTP信号以暂停进程(默认动作), 该信号可以被忽略和重定义。

另外用户在控制终端上输入CTRL-S可以暂停进程的输出, 输入CTRL-Q可以恢复进程的输出。


============================================

SIGSTOP 停止(stopped)进程的执行. 注意它和terminate以及interrupt的区别:

该进程还未结束,只是暂停执行,本信号不能被阻塞、处理或忽略。

对于SIGKILL信号,进程是不能忽略的。这是一个 “我不管您在做什么,立刻停止”的信号。假如您发送SIGKILL信号给进程,Linux就将进程停止在那里。

SIGSTOP是不是让cpu不再执行程序,但是程序不退出,类似于加了个断点。

优化以下代码,并测试stop功能。#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/wait.h> #include <signal.h> #include <ctype.h> #define MAX_INPUT 1024 #define MAX_ARGS 64 // 全局变量记录当前前台进程PID pid_t foreground_pid = 0; // 信号处理器 //设置sigint_handler函数为终止当前的前台进程 void sigint_handler(int sig) { if (foreground_pid != 0) { kill(foreground_pid, SIGKILL); printf("\n"); } } // 设置sigtstp_handler函数为暂停当前的前台进程 void sigtstp_handler(int sig) { if (foreground_pid != 0) { kill(foreground_pid, SIGTSTP); printf("\n[%d] stopped\n", foreground_pid); foreground_pid = 0; } } // 解析输入命令 //将命令行输入input字符串分割成args数组,并返回args数组的长度argc,argc通常会被用来 //调用execvp函数执行外部命令。 int parse_command(char *input, char **args) { int argc = 0; char *token = strtok(input, " \t\n"); while (token != NULL && argc < MAX_ARGS - 1) { args[argc++] = token; token = strtok(NULL, " \t\n"); } args[argc] = NULL; // execvp要求以NULL结尾 return argc; } // 执行外部命令bckground=0表示前台执行,background!=表示后台执行 void execute_external(char **args, int background) { int pipefd[2]; if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } pid_t pid = fork(); if (pid < 0) { perror("fork"); return; } else if (pid == 0) { // 子进程执行命令 close(pipefd[0]); dup2(pipefd[1], STDOUT_FILENO); close(pipefd[1]); if (execvp(args[0], args) < 0) { perror("execvp"); exit(EXIT_FAILURE); } } else { // 父进程处理 if (!background) { printf("前台进程[%d]\n", pid); foreground_pid = pid; close(pipefd[1]); char buf[1024]; ssize_t count; while ((count = read(pipefd[0], buf, sizeof(buf)-1)) > 0) { buf[count] = '\0'; printf("%s", buf); } close(pipefd[0]); int status; waitpid(pid, &status, 0); foreground_pid = 0; } else { printf("后台进程[%d]\n", pid); close(pipefd[0]); close(pipefd[1]); waitpid(pid, NULL, 0); } } } // 内置命令处理 int handle_builtin(char **args, int argc) { if (strcmp(args[0], "exit") == 0) { exit(EXIT_SUCCESS); } else if (strcmp(args[0], "stop") == 0 && argc > 1) { pid_t pid = atoi(args[1]); if (kill(pid, SIGTERM) == 0) { printf("Stopped process %d\n", pid); } else { perror("kill"); } return 1; } return 0; // 不是内置命令 } int main() { char input[MAX_INPUT]; char *args[MAX_ARGS]; // 设置信号处理器 //SIGINT(也就是ctrl+c)绑定函数sigint_handler(终止当前前台进程) //SIGTSTP(也就是ctrl+z)绑定函数sigtstp_handler(暂停当前前台进程) signal(SIGINT, sigint_handler); signal(SIGTSTP, sigtstp_handler); while (1) { printf("mysh> "); fflush(stdout); // 读取输入 ctrl+d退出 if (fgets(input, MAX_INPUT, stdin) == NULL) { break; // 处理EOF (Ctrl+D) } // 解析命令 int argc = parse_command(input, args); if (argc == 0) continue; // 空命令 // 检查后台执行 int background = 0; if (argc > 0 && strcmp(args[argc-1], "&") == 0) { background = 1; args[argc-1] = NULL; argc--; } // 处理内置命令 if (handle_builtin(args, argc)) { continue; } // 执行外部命令 execute_external(args, background); } return EXIT_SUCCESS; }
最新发布
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值