• 数组,父子进程,守护进程


    2015.1.25
    星期日,阴天

    二维数组a中共有m行n列个元素
    从a[0][0]到a[i][j]之间共有i*n+j个元素
    p代表第0行第0列的地址,所以元素a[i][j]的地址为 p + i*n+j

    a[i][j] == p[i*n+j] == *(p + i*n+j)

    在Linux中获得当前进程的PID和PPID的系统调用函数为getpid()和getppid();获得当前PID和PPID后可以将其写入日志备份!

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    int main()
    {
    printf("the pid of this process is %d ",getpid());
    printf("the ppid of this process is %d ",getppid());

    }
    上面程序可以交叉编译下载到目标板上运行!

    父进程调用fork()函数就创建了一个子进程,父进程返回子进程的PID,子进程返回值为0;
    fork()函数开销很大,不能多次使用。

    exec函数族提供了一个在进程中启动另一个进程执行的方法,总共有6个成员函数,使用exec函数时一定
    要加上错误判断语句。exec很容易执行失败。

    守护进程:daemon ,从被执行开始运转,直到真个系统关闭时才退出!

    编写守护进程:

    1.创建子进程,然后父进程退出!
    pid = fork();
    if(pid > 0)
    {
    exit(0);/*父进程退出*/
    }

    2.在子进程中创建新会话:重要一步,意义重大! setsid();

    3.改变当前目录为根目录 :让子进程脱离父进程的文件工作目录。

    4.重设文件权限掩码: 让子进程脱离父进程的文件权限掩码。

    如:050 它就屏蔽了文件组拥有者的可读和可执行权限。用函数umask()实现
    通常的使用方法是:umask(0)

    5.关闭文件描述符

    创建一个守护进程的完整实例:创建守护进程,然后让该进程每隔10S向日志文件/tmp/daemon.log写入一句话。
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcn1.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/wait.h>

    int main()
    {
    pid_t pid;
    int i, fd;
    char *buf = "this is a Daemon ";

    pid = fork(); 第一步
    if(pid < 0)
    {
    printf("error fork ");
    exit(1);
    }
    else if(pid > 0)
    {
    exit(0); 父进程退出
    }

    setsid(); 第二步
    chdir("/"); 第三步
    umask(0); 第四步
    for(i = 0; i < getdtablesize(); i++) 第五步
    {
    close(i);
    }

    /*这时创建完守护进程,以下开始正式进入守护进程工作*/
    while(1)
    {
    if((fd = open("/tmp/daemon.log",O_CREAT|OWRONLY|O_APPEND.0600))<0)
    {
    printf("open file error ");
    exit(1);
    }
    write(fd,buf,strlen(buf) + 1);
    close(fd);
    sleep(10);
    }
    exit(0);
    }

    守护进程出错处理:

    gdb无法调试守护进程,因为已经脱离终端,一种通用的办法就是使用syslog服务,将
    程序中的出错信息输入到系统日志文件中;

    该机制相关的三个syslog函数:openlog();syslog();closelog();
    将上面的程序用syslog服务重写;
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcn1.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/wait.h>

    int main()
    {
    pid_t pid;
    int i, fd;
    char *buf = "this is a Daemon ";

    pid = fork(); 第一步
    if(pid < 0)
    {
    printf("error fork ");
    exit(1);
    }
    else if(pid > 0)
    {
    exit(0); 父进程退出
    }

    openlog("daemon_syslog",LOG_PID,LOG_DAEMON);

    if((sid = setsid() < 0); 第二步
    {
    syslog(LOG_ERR,%s ","setsid");
    exit(1);
    }

    if((sid = chdir("/") < 0); 第三步
    {
    syslog(LOG_ERR,%s ","chdir");
    exit(1);
    }
    umask(0); 第四步
    for(i = 0; i < getdtablesize(); i++) 第五步
    {
    close(i);
    }

    /*这时创建完守护进程,以下开始正式进入守护进程工作*/
    while(1)
    {
    if((fd = open("/tmp/daemon.log",O_CREAT|OWRONLY|O_APPEND.0600))<0)
    {
    syslog(LOG_ERR,"open“);
    exit(1);
    }
    write(fd,buf,strlen(buf) + 1);
    close(fd);
    sleep(10);
    }
    closelog();
    exit(0);
    }

    实验内容:
    有三个进程,其中一个为父进程,其余两个是该父进程的子进程。其中一个子进程运行
    ”ls -l“指令,另一个进程暂停5秒之后异常退出,父进程先用阻塞方式等待第一个子进程的结束,
    然后用非阻塞方式等待另一个进程的退出,待收集到第二个子进程结束的信息,父进程就返回!


    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/wait.h>

    int main(void)
    {
    pid_t child1, child2, child;

    /*创建两个子进程*/
    child1 = fock();
    child2 = fock();

    /*子进程1的出错处理*/
    if(child1 == -1)
    {
    printf("child1 fork error ");
    exit(1);
    }
    else if(child1 == 0) /*在子进程1中调用execlp()函数*/
    {
    printf("in child1:execute 'ls -l' ");
    if(execlp("ls","ls","-1",NULL) < 0)
    {
    printf("child1 execlp error ");
    }
    }

    if(child2 == -1) 子进程2出错处理
    {
    printf("child2 fork error ");
    exit(1);
    }
    else if(child2 == 0) 在子进程2中使其暂停5秒
    {
    printf("in child2:sleep for 5 seconds and then exit ");
    sleep(5);
    exit(0);
    }
    else 在父进程中等待两个子进程的退出
    {
    printf("in father process: ");
    child = waitpid(child1,NULL,0); 阻塞式等待
    if(child == child1)
    {
    printf("get child1 exit code ");
    }
    else
    {
    printf("error occured! ");
    }

    do
    {
    child = waitpid(child2,NULL,WNOHANG); 非阻塞是等待
    if(child == 0)
    {
    printf("the child2 process has not exited! ");
    sleep(1);
    }
    }while(child == 0);

    if(child == child2)
    {
    printf("get child2 exit code ");
    }
    else
    {
    printf("error occured! ");
    }
    }
    exit(0);
    }

    实验内容:
    首先建立起一个守护进程,然后在该守护进程中新建一个子进程,该子进程暂停10秒,
    然后自动退出,并由守护进程收集子进程退出的消息,在这里,子进程和守护进程的退出消息都在
    系统日志文件中输出,子进程退出后,守护进程循环暂停,其间隔时间为10秒。


    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <syslog.h>

    int main(void)
    {
    pid_t child1, child2;
    int i;
    /*创建子进程*/
    child1 = fork();
    if(child1 == 1)
    {
    perror("child1 fork");
    exit(1);
    }

    else if(child1 > 0)
    {
    exit(0); 父进程退出
    }

    openlog("daemon_proc_info",LOG_PID,LOG_DAEMON);
    /*下面几步是编写守护进程的常规步骤*/
    setsid();
    chdir("/");
    umask(0);
    for(i = 0; i < getdtablesize(); i++)
    {
    chose(i);
    }

    child2 = fork(); 创建进程2
    if(child2 == 1)
    {
    perror("child2 fork");
    exit(1);
    }
    else if(child2 == 0) 进入进程2
    {
    syslog(LOG_INFO,"child2 will sleep for 10s"); 在日志中写入字符串
    sleep(10);
    syslog(LOG_INFO,"child2 is going to exit!"):
    exit(0);
    }
    else
    { 进程child1

    waitpid(child2,NULL,0);
    syslog(LOG_INFO,"child1 noticed that child2 has exitde");
    closelog(); 关闭日志服务
    while(1)
    {
    sleep(10);
    }
    }

    }


    **********************************************************************************************************************************************************
    **********************************************************************************************************************************************************
    **********************************************************************************************************************************************************

  • 相关阅读:
    Qt属性动画效果的实现QPropertyAnimation & 自定义属性Q_PROPERTY
    Qt实现鼠标拖拉窗口,并实现模拟鼠标拖拉窗口代码实例
    qt模拟鼠标左击下移动
    Qt新建线程
    Qt中子进程和父进程之间信号和槽通信
    vs2015打开Qt项目出现qt所有头文件都找不到
    vs2015运行Qt项目出现namespace "Ui" 没有成员“XXXClass”
    Opencv Mat类
    cv::cvtColor()的作用
    Delphi 系统[21]关键字和保留字 constructor、destructor、property
  • 原文地址:https://www.cnblogs.com/cnlg/p/4249029.html
Copyright © 2020-2023  润新知