跳到内容

C 编程/stdlib.h/exit

来自维基教科书,自由的教科书

在许多计算机操作系统中,计算机进程通过发出 **exit** 系统调用来终止其执行。更一般地,在多线程环境中,退出意味着执行线程已停止运行。操作系统会回收进程使用的资源(内存、文件等)。该进程在终止后被称为死亡进程

它是如何工作的

[编辑 | 编辑源代码]

在 Unix 和类 Unix 操作系统中,当父进程执行 fork 系统调用时,进程启动。父进程随后可以等待子进程终止,或者可以继续执行(可能派生出其他子进程)。当子进程终止(“死亡”)时,无论是通过调用 exit 正常终止,还是由于致命错误或信号(例如,SIGTERM、SIGINT、SIGKILL)异常终止,都会将退出状态返回给操作系统,并向父进程发送 SIGCHLD 信号。父进程随后可以通过 wait 系统调用检索退出状态。

大多数操作系统允许终止进程向系统提供特定的退出状态,该状态可供父进程使用。通常,这是一个小的整数值,尽管某些操作系统(例如,Plan 9)允许指定一个字符字符串。

退出操作通常在将控制权交回操作系统之前,在进程空间内执行清理操作。一些系统和编程语言允许用户注册子例程,以便在程序实际终止之前,在程序终止时调用这些子例程。作为终止的最后一步,将调用一个原始的系统退出调用,通知操作系统进程已终止,并允许其回收进程使用的资源。

有时可以绕过通常的清理;C99 提供了 _exit() 函数,它在没有任何额外程序清理的情况下终止当前进程。例如,这可以在 fork-exec 例程中使用,此时 exec 调用未能替换子进程;调用 atexit 例程将错误地释放属于父进程的资源。

孤儿和僵尸

[编辑 | 编辑源代码]

某些操作系统以特殊方式处理其父进程已终止的子进程。这种孤儿进程成为一个特殊的根进程的子进程,该进程随后等待子进程终止。同样,类似的策略用于处理僵尸进程,即已终止但其退出状态被其父进程忽略的子进程。这种进程成为一个特殊父进程的子进程,该进程检索子进程的退出状态并允许操作系统完成死亡进程的终止。处理这些特殊情况可以使系统进程表保持一致的状态。

以下程序终止并向系统返回成功的退出状态。

C

#include <stdlib.h>

int main(void)
{
    exit(EXIT_SUCCESS);
}

或者

#include <stdlib.h>

int main(void)
{
    return EXIT_SUCCESS;
}

C++

#include <cstdlib>

int main(void)
{
    std::exit(EXIT_SUCCESS); // or return EXIT_SUCCESS
}

COBOL

IDENTIFICATION DIVISION.
PROGRAM-ID. SUCCESS-PROGRAM.

PROCEDURE DIVISION.
MAIN.
    MOVE ZERO TO RETURN-CODE.
END PROGRAM.

Java

public class Success
{
    public static void main(String[] args)
    {
        System.exit(0);
    }
}

DOS 批处理文件

exit 0

Perl

#!/bin/perl
exit;

PHP

<?php
exit(0);
?>

Python

#!/usr/bin/python
import sys
sys.exit(0)

Unix shell

exit 0

Pascal

program pr1;
begin
 exit(0);
end;

DOS 汇编

; For MASM/TASM
.MODEL SMALL
.STACK
.CODE
main PROC NEAR
    MOV AH, 4Ch ; Service 4Ch - Terminate with Error Code
    MOV AL, 0 ; Error code
    INT 21h ; Interrupt 21h - DOS General Interrupts
main ENDP
END main ; Starts at main

一些程序员可能会一次为 INT 21h 准备所有内容

    MOV AX, 4C00h ; replace the 00 with your error code in HEX

Linux 汇编

; For NASM
MOV AL, 1 ; Function 1: exit()
MOV EBX, 0 ; Return code
INT 80h ; The only interrupt Linux uses!
# For GAS
.text

.globl _start

_start:
    movl $1, %eax  # System call number 1: exit()
    movl $0, %ebx  # Exits with exit status 0
    int $0x80      # Passes control to interrupt vector
                   # invokes system call—in this case system call
                   # number 1 with argument 0

  • SIGCHLD
  • 线程
[编辑 | 编辑源代码]
华夏公益教科书