• unix c 07


    进程的结束函数 (exit、_Exit)
       exit 并不是立即退出,退出前执行 用atexit/on_exit函数 注册的函数。
       exit(int status)中的status可以用 wait函数获取
       _Exit底层调用 Unix的系统调用 _exit,会立即退出,而不会调用任何函数。_Exit的status也可以用wait函数获取。
       进程的调度机制(wait/waitpid)
       wait和waitpid功能是让 父进程等待子进程,如果没有子进程,会立即返回,如果没有结束的子进程,父进程处于 阻塞状态,如果 子进程结束,父进程取得退出状态码 并返回(包括僵尸子进程)。

      区别:
       wait是等待所有子进程中的任意一个结束,waitpid可以等待任意一个(pid=-1),也可以指定某一个(pid>0),waitpid的第三个参数一般给0即可。
      取退出状态:
       用wait(&status)或waitpid(pid,&status,0)可以把退出的信息放入status变量,用WIFEXITED(status)可以判断是否正常退出,用WEXITSTATUS(status)可以取得exit()退出码。
       vfork不复制父进程的内存,功能和fork一样,也是创建一个子进程。vfork在创建时 抢占父进程的内存空间。因此vfork 确保子进程先运行。

       vfork自身意义不大,一般和exec系列函数结合使用。vfork创建一个新的子进程,exec系列函数提供新的代码区和内存存储空间。(exec系列函数不负责创建新进程,只是进程的替换)

       fork是父子进程执行相同的代码段时使用,vfork+exec系列函数是父子进程执行不同的代码段时使用。

    信号(signal)
       信号是一种软件中断技术,中断就是中止当前正在实行的代码,转而执行其他的代码。
       中断分为软件中断和硬件中断。
       常见信号:
          ctrl+c 2信号  ctrl+ 信号3  段错误 总线错误
          浮点数例外(整数除法0做除数)

      信号的本质就是一个整数,有一个宏定义的名字,都是SIG开头,比如2信号 就是SIGINT。
        #define SIGINT 2
      信号可以在进程间互发,类似于进程间通信。
      信号无法确定 何时产生,程序 没法判定信号什么时候会到来。(异步处理)

      在Unix系统中,信号主要来自于:硬件产生和函数调用。
      Unix和Linux在信号的数值上有区别,但 宏定义是一样的。
      kill -l 显示所有的信号(数值和名字)
      经验:编程时 信号用 宏定义比较好,有通用性。

      信号分为 可靠信号和不可靠信号:
          不可靠信号不支持排队,因此当有多个不可靠信号同时到来时,只留下一个,其他会丢失。不可靠信号都是非 实时的,Linux的1-31都是不可靠信号。
          可靠信号支持排队,因此不会丢失。可靠信号是 实时的,Linux的34-64 都是可靠信号。

       信号的处理方式:
           1 默认处理,80%的默认处理都是退出进程。
           2 忽略信号
           3 自定义信号处理函数。
      注:信号9 不能忽略,也不能自定义处理函数。
          当前用户只能给自己的进程发信号,root可以给所有进程发信号。

       signal函数可以 注册(设定)信号的处理方式。
           typedef void (*sighandler_t) (int);
           sighandler_t signal(
           int signum,sighandler_t);
       其中,signum是信号的数值,
          sighandler_t是 处理函数的函数指针(函数名)
          sighandler_t 的值是SIG_IGN 代表忽略
          sighandler_t 的值是SIG_DFL 代表默认

    子进程的信号处理
        子进程如果是fork方式启动,完全照搬父进程对信号的处理方式。父忽略,子也忽略;父自定义函数,子也会调用相同函数。
        如果是vfork+exec方式启动,父忽略,子也会忽略;父自定义函数,子改为默认处理。(子进程找不到父进程的函数)

    如何发送信号??
       1 键盘直接发送
          ctrl+c -> 信号2
          ctrl+ -> 信号3
          ctrl+z -> 信号20
       2 程序出错
          内存没有映射 -> 信号11(段错误)
          总线错误     -> 信号7(Linux中)
       3 kill 命令
          kill -信号 进程ID
       4 系统函数(信号发送函数)
          raise()  kill()  alarm()  sigqueue()

          raise函数只能当前进程发送信号
          kill函数更实用。
          kill(pid_t pid,int signo)

          pid > 0   是指定某个进程(pid)发送
          pid == -1 给有授权的所有进程发送
          pid == 0  给进程组的所有进程发送
          alarm函数设定N秒后产生一个SIGALRM信号(闹钟)

          sigqueue函数可以在发送信号的同时附带其他数据

  • 相关阅读:
    题目1.A乘以B
    题目1.A乘以B
    秋季学习总结
    题目1.A乘以B
    第一周作业
    C语言I博客作业02
    Silverlight中图像的变换(1)
    SQL SERVER 2005安装过程中COM+错误解决!
    c++ 对文件的操作
    JS标准DES加解密
  • 原文地址:https://www.cnblogs.com/elisha-blogs/p/3771159.html
Copyright © 2020-2023  润新知