栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

进程环境(main、进程终止、钩子函数、命令行参数分析)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

进程环境(main、进程终止、钩子函数、命令行参数分析)

main函数
    int main(int argc,char *argv[])
进程的终止情况

正常终止:
从main函数返回
调用exit
调用_exit或_Exit
最后一个线程从其启动例程返回

异常终止:
调用abort
接到一个信号并终止
最后一个线程对其取消请求做出响应

echo $?//打印上一条语句的执行状态

#include 
#include 

int main()
{

        printf("hellon");


        return 0;

}

echo $?显示的是0

相关函数:
exit
------------------ cause normal process termination

   #include 
   void exit(int status);

描述:
The exit() function causes normal process termination and the value of status & 0377 is returned to the parent (see wait(2)). All functions registered with atexit(3) and on_exit(3) are called, in the reverse order of their registration.

atexit//钩子函数//类似C++里的析构函数
---------------------- register a function to be called at normal process termination
注册一个函数,这个函数将会被调用,在进程正常终止的时候

  #include 
   int atexit(void (*function)(void));

例子:

#include 
#include 

static void f1(void)
{
    puts("f1() is working!");
}

static void f2(void)
{
    puts("f2() is working!");
}

static void f3(void)
{
    puts("f3() is working!");
}
int main()
{
    puts("Begin!");

    atexit(f1);
    atexit(f2);
    atexit(f3);


    puts("End!");
    
    exit(0);

}

运行结果:

解说:先打印Begin然后将函数挂在钩子上,在打印End,在函数结束前,最后逆序调用

伪码表示钩子函数的作用:
fd1=open();
if(fd1<0)
{
perror();
exit(1);
}

fd2=open();

if(fd2<0)
{
close(fd1);
perror();
exit(1);
}
…
fd100=open();
if(fd100<0)
{
close(fd1);
close(fd2);
close(fd3);
…
close(fd99);//这样子的不是我们想要的
perror();
exit(1);
}
改善方法,加上钩子函数就好

fd1=open();
if(fd1<0)
{
perror();
exit(1);
}

fd2=open();
atexit();----->close(fd1);

if(fd2<0)
{
perror();
exit(1);
}
atexit();----->close(fd2);
…
fd100=open();
if(fd100<0)
{
perror();
exit(1);
}
atexit();----->close(fd100);

_exit, _Exit //系统调用,exit依赖于它们
----------------- terminate the calling process

   #include 
   void _exit(int status);
   #include 
   void _Exit(int status);

伪代码分析exit和_exit的区别:
int func()
{
return 0/1/2;
}
int main()
{
int f;
f=func();,
…
switch(f)
{
case 0:
case 1:
case 2:
default:
}
}
如果运行到default那么我们可以怀疑,在f=func出现了问题,很有可能是写越界。如果这个时候exit,那么就会调用各种钩子函数,io刷新,该同步的同步,该刷新的刷新。这很有可能导致故障扩大。这个时候我们最好调用_exit,直接退出。或是利用abort();

命令行参数的分析
    getopt();
    getopt_long();//分析长格式

   #include 
   int getopt(int argc, char * const argv[], const char *optstring);
   extern char *optarg;//当分析命令行上串的时候,如果看到摸一个选项加了冒号,那么拿到这个选项的时候,optarg指针默认指向后面修饰的那个串
   extern int optind//表示当前读到的argv的下标, opterr, optopt;
   int getopt_long(int argc, char * const argv[],
              const char *optstring,
              const struct option *longopts, int *longindex);

If the first character of optstring is ‘-’, then each nonoption argv-element is handled as if it were the argument of an option with character code 1 //“-“识别非选项的传参
如果串的第一个字符是”-”,那么遇到每一个非选项参数的时候就会返回1,当我们拿到了这个非选项传参,就会返回1,返回1以后,optind指针就会指向下一个argv

例子:
实现./mydate -y得到年份 -m得到月份等等
对于年份是想要两位的还是四位的,对于小时是想要24小时制的还是12小时制的
如果在终端有文件名,则将内容输出到这个文件上否则就输出到终端

#include 
#include 
#include 
#include 
#include 
#define FMTSTRSIZE 1024
#define TIMESTRSIZE 1024


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

    FILE * fp=stdout;
    time_t stamp;
    char fmtstr[FMTSTRSIZE];
    struct tm *tm;
    char timestr[TIMESTRSIZE];
    int c;
    fmtstr[0]='';
    stamp=time(NULL);
    tm=localtime(&stamp);
    while(1)
    {
        c=getopt(argc,argv,"-H:MSy:md");
        if(c<0)
        {
            break;
        }
        switch(c)
        {
            case 1:
            fp=fopen(argv[optind-1],"w");
            if(fp==NULL)
            {
                perror("fopen()");
                fp=stdout;
            
            }
                break;
            case 'H':
                if(strcmp(optarg,"12")==0)
                {
                    strncat(fmtstr,"%I(%P) ",FMTSTRSIZE);
                }
                else if(strcmp(optarg,"24")==0)
                {
                    strncat(fmtstr,"%H",FMTSTRSIZE);
                }
                else
                    fprintf(stderr,"invalid argument");

                break;
            case 'M':
                strncat(fmtstr,"%M ",FMTSTRSIZE);
                break;
            case 'S':
                strncat(fmtstr,"%S ",FMTSTRSIZE);
                break;
            case 'y':
                if(strcmp(optarg,"2")==0)
                {
                    strncat(fmtstr,"%y ",FMTSTRSIZE);
                }
                else if(strcmp(optarg,"4")==0)
                {
                    strncat(fmtstr,"%Y ",FMTSTRSIZE);
                }
                else
                    fprintf(stderr,"invlid argument");
                break;
            case 'm':
                strncat(fmtstr,"%m ",FMTSTRSIZE);
                break;
            case 'd':
                strncat(fmtstr,"%d ",FMTSTRSIZE);
                break;
            default:
                break;

        }
    }
    strncat(fmtstr,"n",FMTSTRSIZE);
    strftime(timestr,TIMESTRSIZE,fmtstr,tm);
    fputs(timestr,fp);
    if(fp!=stdout)
    {
        fclose(fp);
    }    
    

    exit(0);

}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/942249.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号