【Linux-Day8- 进程替换和信号】

这篇具有很好参考价值的文章主要介绍了【Linux-Day8- 进程替换和信号】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

进程替换和信号

问题引入

【Linux-Day8- 进程替换和信号】,Linux学习,linux

我们发现 终端输入的任意命令的父进程都是bash,这是因为Linux系统是用fork()复制出子进程,然后在子进程中调用替换函数进行进程替换,实现相关命令。

(1) exec 系列替换过程:pcb 使用以前的只修改,进程实体更换。

【Linux-Day8- 进程替换和信号】,Linux学习,linux

进程替换函数

#include <unistd.h>
int execl( const char * path, const char * arg,…);
/*
*path:新替换的程序的路径名称
*arg :传给新程序主函数的第一个参数,一般为程序的名字
*arg 后面是剩余参数列表,参数个数可变,必须以空指针作为最后一个参数
*/
int execlp( const char * file, const char * arg,…);

/*

int execlp( const char * file, const char * arg,…);

/*

*file:新替换的程序的名称
*arg :传给新程序主函数的第一个参数,一般为程序的名字
*arg 后面是剩余参数列表,参数个数可变,必须以空指针作为最后一个参数
*/

int execle( const char * path, const char * arg,…, char * const envp[]);

/*
*path:新替换的程序的路径名称
*arg :传给新程序主函数的第一个参数,一般为程序的名字
*arg 后面是剩余参数列表,参数个数可变,必须以空指针作为最后一个参数

*const envp[] : 存放环境变量

*/

int execv( const char * path, char * const argv[]);

/*
*path:新替换的程序的路径名称

const argv[] :存放命令参数的指针数组

*/

int execvp( const char * file, char * const argv[]);

/*
*file: 新替换的程序的名称

const argv[] :存放命令参数的指针数组

*/

int execve( const char * path, char * const argv[], char * const envp[]);

/*
*path:新替换的程序的路径名称

const argv[] :存放命令参数的指针数组

*const envp[] : 存放环境变量

*/

使用模板如下

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<unistd.h>
#include<string.h>
#include <sys/wait.h>
int main(int agrc,char*argv[],char*envp[]){
    printf("main pid=%d \n",getpid() ); 
    assert(pid!=-1);
    if(pid==0)
    {
        printf("child pid=%d,ppid=%d\n",getpid(),getppid());
      //1.  execl("/bin/ps","ps","-f",(char*)0);
      //2.  execlp("ps","ps","-f",(char*)0);
      //3.  execle("/usr/bin/ps","ps","-f",(char*)0,envp);
        char* myargv[]={"ps","-f",0};
      //4.  execv("/usr/bin/ps",myargv);
      //5.  execvp("ps",myargv);
      //6.  execve("/usr/bin/ps",myargv,envp); 
        exit(0);
    } 
    exit(0);
}

Linux 信号的使用

信号是系统响应某个条件而产生的事件,进程接收到信号会执行相应的操作。
与信号有关的系统调用在“signal.h”头文件中有声明
常见信号的值,及对应的功能说明

【Linux-Day8- 进程替换和信号】,Linux学习,linux

信号的值在系统源码中的定义如下:

  1. #define SIGHUP 1
  2. #define SIGINT 2 //键盘按下 Ctrl+c 时,会产生该信号
  3. #define SIGQUIT 3
  4. #define SIGILL 4
  5. #define SIGTRAP 5
  6. #define SIGABRT 6
  7. #define SIGIOT 6
  8. #define SIGBUS 7
  9. #define SIGFPE 8
  10. #define SIGKILL 9 //该信号的响应方式不允许改变
  11. #define SIGUSR1 10
  12. #define SIGSEGV 11
  13. #define SIGUSR2 12
  14. #define SIGPIPE 13 //读端关闭的描述符,写端写入时产生,该信号会终止程序
  15. #define SIGALRM 14
  16. #define SIGTERM 15 //系统 kill 命令默认发送的信号
  17. #define SIGSTKFLT 16
  18. #define SIGCHLD 17 //子进程结束后,会默认给父进程发送该信号
  19. #define SIGCONT 18
  20. #define SIGSTOP 19
  21. #define SIGTSTP 20
  22. #define SIGTTIN 21
  23. #define SIGTTOU 22
  24. #define SIGURG 23
修改信号的响应方式 – 调用signal()

typedef void (*sighandler_t)(int); //函数指针类型重命名

**sighandler_t ** signal(int signum, sighandler_t sig_fun)

/*

signum : 处理的信号

sig_fun :处理信号的函数

​ 1.SIG_IGN 忽略

​ 2.SIG_DFL 默认

​ 3.自定义:自己写处理信号的函数

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
void fun(int signum)
{
    printf("Call fun \n");
}

int main()
{
    signal(SIGINT,fun);
    while(1)
    {
        sleep(1);
        printf("Hello\n");
    }
    exit(0);
}

运行结果

【Linux-Day8- 进程替换和信号】,Linux学习,linux

发送信号 – kill()

kill() 可以向指定的进程发送指定的信号:

int kill(pid_t pid, int sig);

pid > 0 指定将信号发送个那个进程

pid == 0 信号被发送到和当前进程在同一个进程组的进程

pid == -1 将信号发送给系统上有权限发送的所有的进程

pid < -1 将信号发送给进程组 id 等于 pid 绝对值,并且有权限发送的所有的进程。

sig 指定发送信号的类型。

示例代码:

1.mykill.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>

int main(int argc,char* argv[])
{
    if(argc != 3)
    {
        printf("argc error\n");
        exit(1);
    }
    int pid = atoi(argv[1]);
    int sig = atoi(argv[2]);
    if(kill(pid,sig) == -1)
    {
        printf("kill error\n");
    }
    exit(0);
}


2.test1.c
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<unistd.h>
#include<string.h>
#include<signal.h>

void fun(int signum)
{
    printf("signum=%d \n",signum);
    signal(SIGINT,SIG_DFL);
}

int main()
{
    signal(SIGINT,fun);
    while(1)
    {
        sleep(1);
        printf("Hello\n");
    }
    exit(0);
}

【Linux-Day8- 进程替换和信号】,Linux学习,linux文章来源地址https://www.toymoban.com/news/detail-675084.html

用信号处理fork()僵死进程

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<signal.h>
#include<sys/wait.h>
void fun_sig(int sig)
{
    printf("end fork\n");
    wait(NULL);
}
int main()
{
    char*s=NULL;
    int n=0;
    signal(SIGCHLD,fun_sig);
    pid_t pid=fork();
    if(pid==-1){
        exit(1);
    }
    if(pid==0)
    {
        s="child";
        n=3;
    }
    else
    {
        s="parent";
        n=7;
    }
    int i=0;
    for(;i<n;i++){
        printf("s=%s,pid=%d\n",s,getpid());
        sleep(1);
    }
    exit(0);
}

到了这里,关于【Linux-Day8- 进程替换和信号】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】进程等待和替换——进程等待的原理、wait/waitpid方法、进程程序替换、进程替换原理、替换函数

    1.1进程等待的概念    进程等待指的是父进程等待子进程退出,以获取子进程的退出返回值,并释放子进程占用的资源。    当子进程先于父进程退出,但父进程没有关注子进程的退出状态时, 子进程会为了保存自己的退出状态而保持资源占用, 这种情况被称为“僵尸进

    2024年02月04日
    浏览(43)
  • [Linux 进程控制(二)] 进程程序替换

    首先,我们要认识到,我们之前fork()所创建的子进程,执行的代码,都是父进程的一部分(用if-else分流或者执行同样的代码)! 如果我们想让子进程执行新的程序呢? 执行全新的代码和访问全新的数据,不再和父进程有瓜葛,这种技术就叫做程序替换 ,下面我们就来学习一

    2024年03月14日
    浏览(51)
  • 【Linux】Linux进程控制及程序替换

    🍎 作者: 阿润菜菜 📖 专栏: Linux系统编程 在linux中fork是一个很重要的函数,它可以已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。 fork函数返回两个值,一个是子进程的进程号(pid),另一个是0。 父进程可以通过pid来区分自己和子进程,子进程可

    2024年02月02日
    浏览(46)
  • 【Linux进程控制】进程创建 | 进程终止 | 进程等待 | 进程替换

    【写在前面】 本文主要学习理解 fork 的返回值、写时拷贝的工作细节、为什么要存在写时拷贝;进程退出码、进程退出的场景及常见的退出方法、对比 man 2 _exit 和 man 3 exit;进程终止、操作系统怎么进行释放资源、池的概念;进程等待的价值、进程等待的方法 wait 和 waitpid

    2023年04月08日
    浏览(38)
  • Linux之进程控制&&进程终止&&进程等待&&进程的程序替换&&替换函数&&实现简易shell

    1.1 fork的使用 我们可以使用man指令来查看一下 子进程会复制父进程的PCB,之间代码共享,数据独有,拥有各自的进程虚拟地址空间。 这里就有一个代码共享,并且子进程是拷贝了父进程的PCB,虽然他们各自拥有自己的进程虚拟地址空间,数据是拷贝过来的,通过页表映射到

    2024年04月17日
    浏览(58)
  • 【Linux】Linux进程控制 --- 进程创建、终止、等待、替换、shell派生子进程的理解…

    柴犬: 你好啊,屏幕前的大帅哥or大美女,和我一起享受美好的今天叭😃😃😃 1. 在调用fork函数之后, 当执行的程序代码转移到内核中的fork代码后 ,内核需要分配 新的内存块 和 内核数据结构 给子进程, 内核数据结构包括PCB、mm_struct和页表,然后构建起映射关系 ,同时

    2024年01月16日
    浏览(58)
  • 【Linux】详解进程程序替换

             用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。 调用exec并不创建新

    2024年04月18日
    浏览(44)
  • 【Linux】进程程序替换

    👑作者主页:@安 度 因 🏠学习社区:安度因 📖专栏链接:Linux 进程创建时有两个目标: 执行父进程的部分代码,由自己编写的,通过 if else 分流,让子进程执行的对应任务。 执行和父进程完全不同的程序 执行和父进程完全不同的代码,

    2024年01月16日
    浏览(41)
  • 【Linux】进程的程序替换

    目标:为了让子进程帮父进程执行特定的任务 具体做法:1. 让子进程执行父进程的一部分代码 红框中的代码实际上是父进程的代码,在没有执行fork之前代码就有了,在没有创建子进程之前,父进程的代码加载到内存了,子进程被创建出来是没有独立的代码,这个代码是父进

    2024年01月17日
    浏览(46)
  • Linux :进程的程序替换

    目录 一、什么是程序替换 1.1程序替换的原理 1.2更改为多进程版本 二、各种exe接口 2.2execlp  ​编辑 2.2execv 2.3execle、execve、execvpe 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种

    2024年04月10日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包