首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >进程终止介绍

进程终止介绍

作者头像
Yui_
发布于 2024-10-16 00:58:31
发布于 2024-10-16 00:58:31
32900
代码可运行
举报
文章被收录于专栏:Yui编程知识Yui编程知识
运行总次数:0
代码可运行

在计算机系统中,进程是操作系统分配资源的基本单位,而进程终止则是因为则是因为操作系统由于某种原因结束一个进程的执行。这可能是因为进程完成了某种任务,也可能是因为出现了错误或异常。 创建一个进程的过程:先描述再组织。创建一个内核数据结构,在进行复杂代码和数据。那么终止一个进程的过程和创建一个进程的顺序是相反的,终止一个进程的本质就是:释放曾经的代码和数据所占的空间,释放内核数据结构。

1.利用echo查看进程退出情况

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
echo $?

功能:返回最近一个进程的退出情况。 现在我们来写段hello world的代码,来验证echo的功能。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#incldue <stdio.h>

int main()
{
	printf("hello world\n");
	return 0;
}
查看进程退出情况
查看进程退出情况

可以看到,echo返回的是0。那么这个所谓的0是进程正常退出,还是异常呢?

答案是正常退出,明明在C语言里,0表示假啊。是这样没错啦,但是你要考虑到,进程的退出虽然只有正常和异常之分,可异常退出的情况却存在的着很多种啊,我们需要利用数字来标记这些异常的情况,为此所以才会产生0表示正常退出,而非0的整数表示不同的异常退出。

写一个错误进程来看看吧,查看一个不存在的文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ls hahahaha
返回2
返回2

现在进程的退出码就不是0了,那肯定就说明了这个进程是异常退出的。那么我们怎么才能知道这些错误码所对应的错误信息呢? strerror就出现了,C语言用strerror存储了会遇见的所有出错信息。

2. strerror介绍

先来打印一下2对应什么错误信息吧。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <string.h>

int main()
{
	printf("%s",strerror(2));
	return 0;
}

//打印结果
//No such file or directory

和上面的出错信息差不多呢。 那么我们来看看到底有多少的错误信息吧:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <string.h>
int main()
{
    int i = 0;
    for(i = 0;i<200;++i){
        printf("%s\n",strerror(i));
    }
    return 0;
}
//打印结果
/*
0: Success
1: Operation not permitted
2: No such file or directory
3: No such process
4: Interrupted system call
5: Input/output error
6: No such device or address
7: Argument list too long
8: Exec format error
9: Bad file descriptor
10: No child processes
11: Resource temporarily unavailable
12: Cannot allocate memory
13: Permission denied
14: Bad address
15: Block device required
16: Device or resource busy
17: File exists
18: Invalid cross-device link
19: No such device
20: Not a directory
21: Is a directory
22: Invalid argument
23: Too many open files in system
24: Too many open files
25: Inappropriate ioctl for device
26: Text file busy
27: File too large
28: No space left on device
29: Illegal seek
30: Read-only file system
31: Too many links
32: Broken pipe
33: Numerical argument out of domain
34: Numerical result out of range
35: Resource deadlock avoided
36: File name too long
37: No locks available
38: Function not implemented
39: Directory not empty
40: Too many levels of symbolic links
41: Unknown error 41
42: No message of desired type
43: Identifier removed
44: Channel number out of range
45: Level 2 not synchronized
46: Level 3 halted
47: Level 3 reset
48: Link number out of range
49: Protocol driver not attached
50: No CSI structure available
51: Level 2 halted
52: Invalid exchange
53: Invalid request descriptor
54: Exchange full
55: No anode
56: Invalid request code
57: Invalid slot
58: Unknown error 58
59: Bad font file format
60: Device not a stream
61: No data available
62: Timer expired
63: Out of streams resources
64: Machine is not on the network
65: Package not installed
66: Object is remote
67: Link has been severed
68: Advertise error
69: Srmount error
70: Communication error on send
71: Protocol error
72: Multihop attempted
73: RFS specific error
74: Bad message
75: Value too large for defined data type
76: Name not unique on network
77: File descriptor in bad state
78: Remote address changed
79: Can not access a needed shared library
80: Accessing a corrupted shared library
81: .lib section in a.out corrupted
82: Attempting to link in too many shared libraries
83: Cannot exec a shared library directly
84: Invalid or incomplete multibyte or wide character
85: Interrupted system call should be restarted
86: Streams pipe error
87: Too many users
88: Socket operation on non-socket
89: Destination address required
90: Message too long
91: Protocol wrong type for socket
92: Protocol not available
93: Protocol not supported
94: Socket type not supported
95: Operation not supported
96: Protocol family not supported
97: Address family not supported by protocol
98: Address already in use
99: Cannot assign requested address
100: Network is down
101: Network is unreachable
102: Network dropped connection on reset
103: Software caused connection abort
104: Connection reset by peer
105: No buffer space available
106: Transport endpoint is already connected
107: Transport endpoint is not connected
108: Cannot send after transport endpoint shutdown
109: Too many references: cannot splice
110: Connection timed out
111: Connection refused
112: Host is down
113: No route to host
114: Operation already in progress
115: Operation now in progress
116: Stale file handle
117: Structure needs cleaning
118: Not a XENIX named type file
119: No XENIX semaphores available
120: Is a named type file
121: Remote I/O error
122: Disk quota exceeded
123: No medium found
124: Wrong medium type
125: Operation canceled
126: Required key not available
127: Key has expired
128: Key has been revoked
129: Key was rejected by service
130: Owner died
131: State not recoverable
132: Operation not possible due to RF-kill
133: Memory page has hardware error
134: Unknown error 134
135: Unknown error 135
136: Unknown error 136
137: Unknown error 137
138: Unknown error 138
139: Unknown error 139
......
*/

从代码发现,一共有133个错误信息。

3.自定义退出码

我们可以通过枚举未自定义退出码进行赋值,将退出码设置为全局变量,在每个函数的每一种结果中都需要将退出码进行修改,再通过接受退出码的值翻译为错误信息的字符串。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>

enum{
    SUCCESS = 0,
    DIV_ZERO,
    MOD_ZERO,
};

int errcode = SUCCESS;

int div_cal(int a,int b)
{
    if(b == 0){
        errcode = DIV_ZERO;
        return -1;
    }
    else{
        return a/b;
    }
}
//翻译错误码
char* traErr(int error)
{
    switch(error)
    {
        case SUCCESS:
            return "SUCCESS";
        case DIV_ZERO:
            return "DIV_ZERO";
        case MOD_ZERO:
            return "MOD_ZERO";
        default:
            return NULL;
    }
}

int main()
{
    int ans = div_cal(10,2);
    printf("answer: %d Error:%s\n",ans,traErr(errcode));
    int ans2 = div_cal(10,0);
    printf("answer:%d Error:%s\n",ans2,traErr(errcode));

    return 0;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
打印结果:
answer: 5 Error:SUCCESS
answer:-1 Error:DIV_ZERO

4. 进程终止

4.1 进程退出的场景

  • 代码运行完毕,结果正确。
  • 代码运行完毕,结果不正确。
  • 代码异常终止。

4.2 进程常见的退出方法

正常退出:

  1. 从main返回。
  2. 调用exit。
  3. \_exit 异常退出:

ctrl + c,信号终止。

当进程死循环时,除了使用ctrl+c外,还可以使用kill -9 pid来杀死进程。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <unistd.h>

int main()
{
    while(1){
        printf("i am a process,pid = %d\n",getpid());
        sleep(1);
    }
    return 0;
}
kill 进程
kill 进程

4.3 exit函数和_exit函数

_exit 函数参数:status定义进程的终止状态,父进程通过wait来获取该值。 说明:虽然status是int类型,但是仅仅有8位可以被父进程使用,所以_exit(-1)时,在终端执行echo $?会发现返回值是255。这里运用到的是状态压缩。 exit eixt函数最后会调用_exit函数,但是在调用前还会做一些其他操作。

  • 执行用户通过atexit或者on_exit定义的清理函数。
  • 关闭所有打开的流,所有的缓存数据均被刷新。
  • 调用_exit。 验证第二点
  • 代码调用exit函数,在进程退出后,会刷新缓冲区。
  • 系统调用_exit函数,在进程退出后,不会刷新缓冲区。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("hahah"); //注意不要写\n,使用\n会直接刷新数据
    exit(1);
    return 0;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
    printf("hahah");
    _exit(1);
    return 0;
}

mybin2为调用exit函数的可执行文件 mybin3为_调用exit函数的可执行文件

缓冲区
缓冲区

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2wnen263eb6sk

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
算法_两数之和&中位数
你需要实现的函数 twoSum 需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 n-1。
OBKoro1
2020/10/27
3090
算法-统计数字(中等)
在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],我们发现 1 出现了 5 次 (1, 10, 11, 12)
OBKoro1
2020/10/27
3970
算法-爬楼梯 2
一个小孩爬一个 n 层台阶的楼梯。他可以每次跳 1 步, 2 步 或者 3 步。实现一个方法来统计总共有多少种不同的方式爬到最顶层的台阶
OBKoro1
2020/10/27
4560
算法-丑数(中等)
我再提供多一些数据:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
OBKoro1
2020/10/27
3700
算法-判断字符串的循环移动
可以检验某个单词是否为另一个单词的子字符串。给定 s1 和 s2,请设计一种方法来检验 s2 是否为 s1 的循环移动后的字符串。
OBKoro1
2020/10/27
7900
三刷”数组中的第K个最大元素“,我终于学会了堆排序
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情
虎妞先生
2022/10/27
5610
三刷”数组中的第K个最大元素“,我终于学会了堆排序
算法—第一个只出现一次的字符
第一个只出现一次的字符 难度:简单 描述: 给出一个字符串,找出第一个只出现一次的字符。 样例: 对于 aabc, b为第一个只出现一次的字符. 对于 abaccdeff, b为第一个只出现一次的字符. 思路分析: 可以用对象保存字符出现的次数。 代码模板: const firstUniqChar = function(str) {}; 想一想再看答案 想一想再看答案 想一想再看答案 代码: 将值删除,用 indexOf 查找还有没有相同字符,并查找之前删过的字符 const firstUniqChar
OBKoro1
2020/10/27
5590
算法-原地删除数组元素
切勿直接使用数组的length属性,因为被删除后length属性会减少,导致遍历提前结束,删除不彻底。
OBKoro1
2020/10/27
1K0
算法_爬楼梯
假设你正在爬楼梯,需要 n 步你才能到达顶部。但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部?
OBKoro1
2020/10/27
3480
一天一大 leet(数组中的第 K 个最大元素)难度:中等 DAY-29
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
前端小书童
2020/09/24
3960
一天一大 leet(数组中的第 K 个最大元素)难度:中等 DAY-29
算法-相亲数
一对整数是相亲数是说他们各自的所有有效因子(除了自己以外的因子)之和等于另外一个数。比如(220, 284)就是一对相亲数。
OBKoro1
2020/10/27
9110
JS数组操作
当前字符串中包含字母和数字, 用一个方法实现出现最多的字母和数字 a)如果只有字母, 那么只返回出现最多的字母, 只有数字情况同理 b)如果有相同次数多的字母或数字出现,将按照第一次出现的顺序返回 列表如下:
epoos
2022/06/06
9.5K0
前端算法专栏-数组-215. 数组中的第K个最大元素
很多朋友也是看着这套系列算法拿到很多offer!所以也是想分享给更多朋友,帮助到有需要的朋友。
程序员库里
2023/11/28
2520
算法-落单的数
给出 2*n + 1 个的数字,除其中一个数字之外其他每个数字均出现两次,找到这个数字。
OBKoro1
2020/10/27
3590
算法—字符串压缩
例如,字符串 aabcccccaaa 可压缩为 a2b1c5a3 。而如果压缩后的字符数不小于原始的字符数,则返回原始的字符串。
OBKoro1
2020/10/27
2.2K0
算法_比较字符串&字符串密钥格式
比较两个字符串 A 和 B,确定 A 中是否包含 B 中所有的字符。字符串 A 和 B 中的字符都是 大写字母
OBKoro1
2020/10/27
9610
LeetCode *703. 数据流中的第 K 大元素(堆)
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。
SakuraTears
2022/01/13
5600
数组中的第K个最大元素
在未排序的数组中找到第k个最大的元素。请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素。
WindRunnerMax
2020/08/27
1.4K0
LeetCode刷题(二) JavaScript
通过递归实现:判断 list1 和 list2 那个链表的头结点的值更小,然后递归下去决定下一个添加到结果的节点,当两个链表中有为空时,递归结束。
赤蓝紫
2023/01/05
3310
2025-01-24:最小元素和最大元素的最小平均值。用go语言,你有一个空的浮点数数组 averages,以及一个包含偶数个整
2025-01-24:最小元素和最大元素的最小平均值。用go语言,你有一个空的浮点数数组 averages,以及一个包含偶数个整数的数组 nums。你需要执行以下步骤,重复 n/2 次:
福大大架构师每日一题
2025/02/05
700
2025-01-24:最小元素和最大元素的最小平均值。用go语言,你有一个空的浮点数数组 averages,以及一个包含偶数个整
相关推荐
算法_两数之和&中位数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档