ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

进程环境之main函数、进程终止、命令行参数以及环境表

2020-02-20 22:41:40  阅读:237  来源: 互联网

标签:函数 int void 环境 exit 进程 main my


文章目录

main函数

C程序总是从main函数开始执行。main函数原型是:

int main(int argc, char *argv[]);

argc是命令行参数个数,argv是指向参数的各个指针所构成的数组。

当内核执行C程序时,在调用main函数前先调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址——这是有连接编辑器设置的,而连接编辑器则由C编辑器调用。启动例程从内核取得命令行参数和环境变量值,然后按上述方式调用main函数做好安排。

进程终止

有8中方式使进程终止,其中有5种为正常终止,它们是:

  • main返回
  • 调用exit
  • 调用_exit_Exit
  • 最后一个线程从其启动例程返回
  • 从最后一个线程调用pthread_exit

异常终止有3种方式,它们是:

  • 调用abort函数
  • 接到一个信号
  • 最后一个线程对取消请求做出响应

1. 退出函数

3个用于正常终止的函数。_exit_Exit函数立即进入内核,exit函数先执行一些清理处理,然后返回内核。

#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);

main函数返回一个整型值与该值调用exit是等价的。于是在main函数中exit(0);等价于return (0);

测试示例:

#include <stdio.h>
main()
{
    printf("hello, world\n");
}

2. 函数atexit

按照ISO C的规定,一个进程可以登记多至32个函数,这些函数将由exit函数自动调用。这些函数被称之为终止处理程序,并调用atexit函数来登记这些函数。

#include <stdlib.h>
int atexit(void (*func)(void));
返回值:若成功,返回 0;若出错,返回非 0。

atexit函数的参数是一个函数地址,当调用此函数时无需向它传递任何参数,也不期望它返回一个值。exit函数调用这些函数时的顺序与它们被登记时的顺序相反。同一函数如果被登记多次,也会被调用多次。
测试示例:

#include "../../include/apue.h"

static void my_exit1(void);
static void my_exit2(void);

int main(void)
{
    if(atexit(my_exit2) != 0)
        err_sys("can't register my_exit2");

    if(atexit(my_exit1) != 0)
        err_sys("can't register my_exit1");
    if(atexit(my_exit1) != 0)
        err_sys("can't register my_exit1");

    printf("main is done\n");
    return 0;
}

static void my_exit1(void)
{
    printf("first exit handler\n");
}

static void my_exit2(void)
{
    printf("second exit handler\n");
}

结果如下:

由上图可知,终止处理函数的执行顺序与它们的注册顺序是相反的,并且my_exit1函数两次被注册,则其就被执行两次。

命令行参数

当执行一个程序时,调用exec的进程可将命令行参数传递给该新程序。这是UNIX shell的一部分常规操作。
测试示例:
将所有命令行参数回显到标准输出上,但是,通常的echo程序无法回显第0个参数。

#include "../../include/apue.h"

int main(int argc, char *argv[])
{
    int i;
    //for(i = 0; i < argc; i++)
    for(i = 0; argv[i] != NULL; i++)    
        printf("argv[%d]: %s\n", i, argv[i]);
    return 0;
}

结果如下:

环境表

每个程序都接收到一张环境表,与参数表一样,环境表也是一个字符指针数组,其中每个指针包含一个以null(’\0’)结束的C字符串的地址。全局变量environ则包含了该指针数组的地址:

extern char **environ;

我们称environ为环境指针,指针数组为环境表,其中各指针指向的字符串为环境字符串。在历史上,大多数UNIX系统支持main函数带3个参数,其中第3参数就是环境表地址:

int main(int argc, char *argv[], char *envp[]);

因为ISO C规定main函数只有两个参数,而且第3个参数与全局变量environ相比并未带来更多益处,所以POSIX.1也规定应使用environ而不是第3个参数。通常使用getenvputenv函数来访问环境变量,而不是用environ变量。但是,如果要查看整个环境,则必须使用environ指针。

Dunk.Wan 发布了229 篇原创文章 · 获赞 17 · 访问量 1万+ 私信 关注

标签:函数,int,void,环境,exit,进程,main,my
来源: https://blog.csdn.net/qq_40073459/article/details/104419018

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有