zoukankan      html  css  js  c++  java
  • 孙子进程和共享内存的应用

    fork两次然后在孙子进程中调用某函数避免孙子进程被kill掉产生僵尸进程 

    /* 这样做儿子进程很快就会退出,所以孙子进程不太可能产生僵尸进程,即使产生时间也极其短暂 */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    void fork_grandson_run(void func(void));
    void print_name(void);
    int main(void)
    {
    int i;
    for (i = 0; i < 10; i++) {
    fork_grandson_run(print_name);
    }
    return 0;
    }
    void print_name(void)
    {
    // printf("my name is zhangbolun ");
    execlp("ls", "ls", "-a", NULL);
    }
    void fork_grandson_run(void func(void))
    {
    pid_t pid, pid2;
    pid = fork();
    if (pid < 0) {
    perror("fork failed ");
    exit(1);
    } else if (pid == 0) { // son
    pid2 = fork();
    if (pid2 < 0) {
    perror("fork failed ");
    exit(1);
    } else if (pid2 == 0) {
    func();
    exit(0);
    } else {
    exit(0);
    }
    } else { // parent
    // do nothing
    }
    }

    需要注意是:

    wait()函数不能等待孙子进程,可以等待子进程

    for(;wait((int*)0)>0;);这里的for循环的作用就是等到退出成功才往下运行,否则一直在等待;

    共享内存的应用


    /*共享内存申请标记*/
    #define PERM S_IRUSR|S_IWUSR


    /*孙子进程id号*/
    pid_t gradchild;

    /*子进程id号*/
    pid_t pid;

    /*共享内存描述标记*/
    int shmid;


    /*共享内存:用于存放子进程ID,播放列表位置*/
    if((shmid = shmget(IPC_PRIVATE,5,PERM))== -1)
    exit(1);

    //内存映射

    p_addr = shmat(shmid,0,0);


    /*内存映射*/
    c_addr = shmat(shmid,0,0);

    /*把孙子进程的id和当前播放歌曲的节点指针传入共享内存*/
    memcpy(c_addr,&fd,sizeof(pid_t));
    memcpy(c_addr + sizeof(pid_t)+1,&currentsong,4);

    /*把孙子进程的pid传给父进程*/
    memcpy(&gradchild,p_addr,sizeof(pid_t));

    最后补充:

    共享内存是进程间通信(IPC)的一种。因为进程在使用共享内存时,可以直接读写内存,不需 要任何数据拷贝,所以它的效率是最高的。关于共享内存是内核专门留出来的一块内存,这段内存可以让访问的进程映射到自己的私有地址空间,从而可以操作共享 内存。 共享内存可以让不同的进程来映射地址,从而实现了进程之间的通信。

    多个程序都来操作共享内存,需要一种同步机制,下面来介绍信号同步的机制。

    共享内存的实现分为三步:第一步是创建共享内存,用的函数是shmget()函数;第二步是映射共享内存,用的函数是shmat();最后一步是撤销映射,用的函数是shmdt()。


    建立好共享内存后,我是用信号来实现同步机制的,当然也可以用信号量等其他的。 使用信号需要了解kill()信号发送函数和signal()捕捉信号函数。首先kill函数需要知道对方进程的进程号,所以第一步就是获得对方的进程 号,可以通过共享内存获得。然后获得自己的进程号再通过共享内存发给对方。


    这样当一个进程操作完以后,就可以发信号给另一个进程,实现了进程之间的同步。



  • 相关阅读:
    Mybatis的缓存
    Mybatis使用assocation和Collection实现延迟加载
    Mybatis:一对多的查询
    Mysql:事务
    Mysql:多表查询
    Mysql:数据库的设计
    Mysql:约束
    MYSQL:DQL-查询表中的记录
    panic: cannot create context from nil parent
    $request input 获取参数null
  • 原文地址:https://www.cnblogs.com/God-boy1/p/3704252.html
Copyright © 2011-2022 走看看