• LINUX C系统编程学习笔记进程通信(二)


    进程通信(二)

                

     信号通讯

    1.常见的信号类型:

    SIGHUP 从终端发出的结束信号

    SIGINT 来自键盘的终断信号(ctrl-c)

    SIGKILL 该信号结束接收信号的进程

    SIGTERM  kill命令发出的信号

    SIGSTOP  来自键盘(ctrl-z)或调试程序的停止执行信号

    2.发送信号的主要函数有kill和raise

    区别:

    kill既可向自身发送信号,也可以像其他进程发送信号

    raise只向进程自身发送信号

    #include <sys/types.h> 

       #include <sysnal.h>

    int kill(pid_t pid,int signo);

    int raise(int signo);

    kill的pid参数:

    ①,pid > 0 将信号发送之后进程ID为PID的进程

    ②,pid == 0 将信号发送给其他进程组的进程

    ③,pid < 0 将信号发送给其他进程组ID等于PID绝对值的进程 

    ④,pid == -1 将信号发送给所有的进程

    3.“闹钟函数”

    #include <unistd.h>

        unsignd int alarm(unsigned int seconds);

    经过seconds秒后,会产生SIGALRM信号,如果不捕捉此信号,则默认动作是终止该进程

    4.”挂起“----pause

    pause函数使调用进程挂起直至捕捉到一个信号

    #include <unistd.h>

       int pause(void);

    只有执行一个信号处理函数后,挂起来才结束。

    5.signal

    #include <signal.h>

    void (* signal (int signo,void (*func) (int))) (int)  )

      || )

    \/ ) ====> 这个是真的不好理解啊!

    typedef void (* sighandler_t)(int)         )

    sighandler_t signal (int signum,sighandler_t handler)  )

    func可能的值是:

    1. SIG_IGN 忽略此信号

    2. SIG_DFL 按系统默认方式处理

    3.信号处理函数 使用该函数处理

    例:

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>

    void my_func(int sign_no)
    {
        if (sign_no == SIGINT)
            printf("I have get SIGINT\n");
        else if (sign_no == SIGQUIT)
            printf("I have get SIGQUIT\n");
    }
    int main(void)
    {
        printf("waiting for signal SIGINT or SIGQUIT\n");

    //  注册信号处理函数 

        signal(SIGINT,my_func);
        signal(SIGQUIT,my_func);
        pause();
        exit(0);


    运行程序后·······使用ps aux看看这个程序的pid

    在使用kill命令试着给它发送SIGINT或者SIGQUIT信号,看看结果 

    共享内存 

    1,定义:被多个进程共同使用的一段物理内存。

    2,创建共享内存

    int shmget(ket_t key,int size,int shmflg); //size是创建共享内存的大小

    key标示共享内存的键值:O/IPC_PRVIATE,当key的取值为IPC_PRIVATE,则函数shmget()将创建一块新的共享内存,如果key的取值为0,而参数shmflg中又设 置IPC_PIRVATE这个标志,则会同样创建一块新的共享内存。 

    返回值:成功,则返回共享内存标示符,失败则返回-1.

     3,映射

    int shmat(int shmid,char *shmaddr,int flag);

    shmid: shmget 函数返回的共享存储标示符

    shmaddr:假如为0 的话,系统自动指定地址

    flag:决定以什么方式来确定映射的地址(通常为0)

    返回值:

    如果成功,则返回共享内存映射到进程中的地址,失败则返回-1

    当一个进程不在需要共享内存时,需要把它从进程地址空间中脱离

    intshmadt(char * shmaddr);

    例:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>

    #define PERM S_IRUSR|S_IWUSR

    //    共享内存

    int main(int argc,char ** argv)
    {
        int shmid;
        char *p_addr,*c_addr;
        if (argc != 2)
        {
            fprintf(stderr,"Usage: %s\n\a",argv[0]);
            exit(1);
        }

    //    创建共享内存

        if ((shmid = shmget(IPC_PRIVATE,1024,PERM)) == -1)
        {
            fprintf(stderr,"Creat Share Memory Error: %s\n\a",strerror(errno));
        exit(1);
        }

    //    创建子进程

        if (fork()) // 父进程写
        {
            p_addr = shmat(shmid,0,0);
            memset(p_addr,'\0',1024);
            strncpy(p_addr,argv[1],1024);
            wait(NULL);
            exit(0);
        }
        else        // 子进程读
        {
            sleep(1);
            c_addr = shmat(shmid,0,0);
            printf("Client get %s \n",c_addr);
            exit(0);
        }

    欢迎大神指针批评····

    ----------------------------------------------在穷无非讨饭,不死终会出头。
  • 相关阅读:
    汇编语言-子程序调用
    汇编语言-转移指令的原理
    汇编语言-直接定址表
    汇编语言-内中断
    汇编语言-汇编程序初识
    【Mybtais】Mybatis 插件 Plugin开发(一)动态代理步步解析
    【Redis】redis异步消息队列+Spring自定义注解+AOP方式实现系统日志持久化
    【ECharts】报表联动,动态数据设计
    【】POST、GET、RequestParam、ReqestBody、FormData、request payLoad简单认知
    【TensorFlow】Win7下使用Object Detection API 训练自己的数据集,并视频实时检测
  • 原文地址:https://www.cnblogs.com/scrat/p/2563306.html
Copyright © 2020-2023  润新知