20155335 第十四周博客

我觉得学的最low的还是第八章异常控制流,并没有做过此章的课下实践,是要认真对待该章了,毕竟“困难的是越做会越容易”。

本章有以下几个要点

1.Linux 86-64系统调用

        已知任何系统可以被c语言的syscall函数且所有的关于Linux系统调用的参数都要通过通用寄存器去传递。

       %rax包含的系统调用号有%rdi,%rsi,%rdx。

2.系统调用错误处理

       使用错误处理包装函数。对于给定的函数foo,定义一个具有相同函数的包装函数Foo,包装函数再调用基本函数。例如包装函数如下:

     pid_t  Fork(void)

     {

          pid_t pid;

          if((pid = fork())<0)

             unix_error("Fork error");

          return pid;

     }

故,对fork的调用就可以直接写成;

  pid = Fork();

3.进程控制

1.getpid返回调用进程PID;

2.getppid返回父进程的PID;

3.exit终止进程;

4.fork创建子进程;

5.waitpid等待它的子进程终止或停止

6.sleep函数经一个进程挂起一段指定的时间。

7.pause函数让调用函数休眠,直到该进程收到一个信号。

8.execve函数在当前进程的上下文中加载并运行一个新程序。

使用fork()创建新进程:

#include “csapp.h"

int main()

{

      pid_t pid;

      int x = 1;

      pid = Fork();

     if(pid==0) {

     /*child*/

     printf("child : x=%d\n",++x);

     exit(0);

  }

   /*父进程*/

      printf(”parent:x=%d\n",--x);

}

用户层的异常--信号

信号提供一种机制,通知用户机制发生了这些异常。

传送一个信号到目的进程是由两个不同步骤组成的:

  1.发送信号。

  2.接受信号

注释:对于待处理信号,在任何时刻,一种类型至多只会有一个待处理信号,一个待处理信号最多接收一次。

发送信号的机制

 1. */bin/kill程序可以向另外的进程发送任意的信号。

2.从键盘发送信号。比如:在键盘上输入Ctrl+C会导致发送一个SIGINT型号,终止前台作业

3.调用kill函数发送信号给其他进程。

父进程用kill函数发送一个SIGKILL信号给他的子进程。

#include "csapp.h"

int main()
{
    pid_t pid;

    if ((pid = Fork()) == 0) {  
    Pause(); 
    printf("control should never reach here!\n");
    exit(0);
    }

    Kill(pid, SIGKILL);
    exit(0);
}

 

接收信号的机制

进程可以通过signal函数修改和信号相关联的默认行为。除SIGSTOP和SIGKILL的默认行为不能修改。

在书上的示例程序中,捕获了通过键盘发送的SIGINT信号,默认行为是立即终止该进程,这里修改为输出一条消息,终止该进程。

 

#include "csapp.h"

void handler(int sig) 
{
    printf("Caught SIGINT\n");
    exit(0);
}

int main() 
{
    if (signal(SIGINT, handler) == SIG_ERR) 
    unix_error("signal error");
    
    pause(); 
    
    exit(0);
}

 

 

  

posted on 2017-12-24 23:26  愤怒的小鸟哭了  阅读(196)  评论(0编辑  收藏  举报