zoukankan      html  css  js  c++  java
  • 进程间通信

    复习:
    进程创建
    fork();

    进程终止
    exit(0)/return 0;

    进程等待
    wait()/waitpid(pid,NULL,0);

    进程替换
    exec函数族

    ------------------------
    1.system()函数
    system - execute a shell command
    #include<stdlib.h>
    int system(const char *command);
    system - execute a shell command

    system("ls -l");

    ---------------------
    进程间通信
    1.基本概念
    两个/多个进程之间的数据交换/交流,叫做进程间通信。

    2.通信方式
    1.文件
    2.信号
    3.管道
    4.共享内存
    5.消息队列
    6.信号量
    7.网络编程
    ...
    其中456三种通信方式,称为XSI/IPC
    (X/open system interface inter-process communication)

    3.中断
    中断-表示暂时停止当前进程的执行转而去执行新程序或处理意外情况的过程,叫做中断
    中断分为软件中断和硬件中断

    4.信号的处理
    1.信号的本质就是软中断,它可以作为进程间通信的一种方式,更重要的是,信号是可以中断一个正常运行的程序,更多的被用来处理意外情况。
    2.信号的特点:
    a.信号是异步的,进程不知道信号何时到达
    b.进程可以处理信号,还可以发送信号给指定的进程
    c.每个信号都有一个名字,并且使用SIG开头。

    3.基本命令
    kill -l 查看系统所支持的所有信号
    需要掌握的信号有:
    ctrl + c 发送信号 2 SIGINT 默认处理方式终止进程
    ctrl + 发送信号 3 SIGQUIT 默认处理方式终止进程
    kill -9 发送信号 9 SIGKILL 默认处理方式终止进程

    4.信号的分类
    linux支持的信号范围是1-64,不保证连续
    unix支持的信号范围是1-48
    其中1-31之间的信号 叫不可靠信号,不支持排队,信号可能丢失,也叫非实时信号
    其中34-64之间的信号 叫可靠信号,支持排队,也叫实时信号

    5.信号的处理方式
    1.默认处理 大多数信号的默认处理方式都是终止进程
    2.忽略处理
    3.自定义处理 只需要写一个信号处理函数就可以

    注:
    1.信号SIGKILL只能进行默认处理,不能忽略,也不能自定义处理
    2.信号的发送受到用户权限的影响,也就是每个用户只能给自己的进程发信号。root用户可以给所有的进程发信号。

    3.信号0有特殊用途,本身不代表任何事件,也不会处理,用于测试用户是否有权限发信号
    kill -0 1


    6.信号处理的实现步骤:
    1.写一个信号处理函数
    2.用signal注册信号处理方式

    函数指针 signal(int 信号,函数指针);
    这个函数指针的格式:
    void (*func)(int);
    功能:
    当signal(信号,函数指针)执行完毕后,只要有信号来,系统就会调用这个函数指针所对应的函数。

    第一个参数:信号名称/数值(表示要处理哪一个信号)
    第二个参数:信号的处理方式:
    SIG_DFL 默认处理
    SIG_IGN 忽略处理
    函数指针 自定义函数处理
    返回值:
    成功返回之前的处理方式,失败返回SIG_ERR

    练习:
    设置对信号2进行自定义处理
    信号3进行忽略处理
    对信号9进行默认处理
    使用fork创建子进程,打印子进程的PID,让子进程无限循环,父进程直接结束
    在另一个终端使用kill命令给子进程发送上述3种信号,观察处理结果。


    结论:对于fork出来的子进程,完全照搬父进程对信号的处理方式。


    7.kill()函数

    kill - send signal to a process
    #include <sys/types.h>
    #include <signal.h>
    int kill(pid_t pid, int sig);
    功能:主要用于给指定的进程发送指定的信号
    pid:进程号(给哪一个进程发送信号)
    sig:信号值/信号名称
    返回值:成功返回0
    失败返回-1,errno被设置

    8.raise()函数
    int raise(int sig);
    功能:主要用于给正在调用的进程发送参数指定的信号
    返回值:成功返回0
    失败返回非0
    9.alarm函数
    unsigned int alarm(unsigned int seconds);
    功能:主要用于根据参数 指定的秒数之后,发送SIGALRM信号
    成功返回上一个闹钟没来得及响的秒数,之前没有闹钟则返回0
    当参数使用0时,之前设置的闹钟全部取消


    10.pause()函数
    int pause(void);
    用来等待一个信号的到来,会导致调用进程休眠,直到收到一个信号(被干掉/执行信号处理函数)


    /*************************************************************************
    > File Name: alarm.c
    > Author: csgec
    > Mail: longer.zhou@gmail.com
    > Created Time: Tue 09 Aug 2016 04:42:07 PM CST
    ************************************************************************/

    #include<stdio.h>
    #include<signal.h>
    void sigHander(int signo)
    {

    if(signo == SIGALRM)
    {
    printf("REcv signal %d ",signo);
    }
    }
    int main()
    {
    signal(SIGALRM,sigHander);

    int r = alarm(10);
    printf("r = %d ",r);
    sleep(3);
    r = alarm(10);
    printf("r = %d ",r);
    while(1)
    {

    }

    }

    /*************************************************************************
    > File Name: kill.c
    > Author: csgec
    > Mail: longer.zhou@gmail.com
    > Created Time: Tue 09 Aug 2016 04:26:55 PM CST
    ************************************************************************/

    #include<stdio.h>
    #include<signal.h>
    #include<unistd.h>
    int main()
    {
    pid_t pid;
    pid = fork();

    if(pid == 0)
    {
    while(1);
    }
    else if(pid > 0)
    {
    int signo;
    scanf("%d",&signo);
    kill(pid,signo);
    system("ps -aux");
    }

    return 0;
    }

    /*************************************************************************
    > File Name: pause.c
    > Author: csgec
    > Mail: longer.zhou@gmail.com
    > Created Time: Tue 09 Aug 2016 04:52:51 PM CST
    ************************************************************************/

    #include<stdio.h>
    #include<signal.h>
    #include<stdlib.h>
    void sigHander(int signo)
    {
    printf("Recv SIGALRM signal ");
    }
    int main()
    {
    signal(SIGALRM,sigHander);
    alarm(10);
    while(1)
    {
    pause();
    printf("hello world ");
    }
    exit(0);
    }

    /*************************************************************************
    > File Name: signal1.c
    > Author: csgec
    > Mail: longer.zhou@gmail.com
    > Created Time: Tue 09 Aug 2016 03:11:35 PM CST
    ************************************************************************/

    #include<stdio.h>
    #include<signal.h>
    void myfunc(int signo)
    {
    printf("Recv signal %d ",signo);
    if(signo == SIGINT)
    {

    }
    if(signo == SIGUSR1)
    {

    }
    }
    int main()
    {
    signal(SIGINT,myfunc);
    signal(SIGQUIT,SIG_IGN);
    signal(SIGKILL,myfunc);
    printf("信号处理程序1 ");
    pid_t pid = fork();
    if(pid == 0)
    {
    while(1);
    }
    printf("pid = %d ",pid);
    }

  • 相关阅读:
    gcc代码反汇编查看内存分布[1]: gcc
    centos5.5 安装git
    裸机代码(uboot) : clear bss
    互联网协议入门
    git从github下载代码
    linux账户管理(centos)
    jz2440: linux/arch/arm/下面的plat-和mach-
    位置无关码
    【漫画】什么是外部排序?【转】
    快速排序 Vs. 归并排序 Vs. 堆排序——谁才是最强的排序算法
  • 原文地址:https://www.cnblogs.com/liudehao/p/5758343.html
Copyright © 2011-2022 走看看