zoukankan      html  css  js  c++  java
  • qt新进程工作目录的设置(工作目录确实是被子进程继承的,但也可以设置)

       经过试验,qt启动一个新的进程时,这个进程的工作目录是继承父进程的,无论是通过start还是startDetached来启动。

        其实对于linux系统,qt底层应该也是调用fork、exec之类的函数,对于fork,参看apue中文版第三版,有以下解析:

    在f o r k之后处理文件描述符有两种常见的情况:
    (1) 父进程等待子进程完成。在这种情况下,父进程无需对其描述符做任何处理。当子进
    程终止后,它曾进行过读、写操作的任一共享描述符的文件位移量已做了相应更新。
    (2) 父、子进程各自执行不同的程序段。在这种情况下,在 f o r k之后,父、子进程各自关闭
    它们不需使用的文件描述符,并且不干扰对方使用的文件描述符。这种方法是网络服务进程中
    经常使用的。
    除了打开文件之外,很多父进程的其他性质也由子进程继承:
    • 实际用户I D、实际组I D、有效用户I D、有效组I D。
    • 添加组I D。
    • 进程组I D。
    • 对话期I D。
    • 控制终端。
    • 设置-用户- I D标志和设置-组- I D标志。
    • 当前工作目录。
    • 根目录。
    • 文件方式创建屏蔽字。
    • 信号屏蔽和排列。
    • 对任一打开文件描述符的在执行时关闭标志。
    • 环境。
    • 连接的共享存储段。
    • 资源限制。
    父、子进程之间的区别是:
    • fork的返回值。
    • 进程I D。
    • 不同的父进程I D。
    • 子进程的t m s _ u t i m e , t m s _ s t i m e , t m s _ c u t i m e以及t m s _ u s t i m e设置为0。
    • 父进程设置的锁,子进程不继承。
    • 子进程的未决告警被清除。
    • 子进程的未决信号集设置为空集。

        由以上分析知,工作目录确实是被子进程继承的。个人理解qt的setWorkingDirectory相当于:fork后的chdir,而qt新进程的start或者startDetached相当于exec族的某一个。

        再来谈回qt,在没有设置子进程的工作目录的情况下,假如新的进程代码里面使用了相对路径,那么这个相对路径相对的是父进程的工作目录,而不是传递给start还是startDetached的第一个参数里面的路径。那么问题来了,如果新的进程是要使用相对路径来读写配置文件的情况下,这个配置文件的读写将会在父进程的工作目录进行,这无疑是会有很大问题的。

        针对以上问题,个人进行了以下试验并总结。

        //两种办法都可以获取当前进程的路径
        QString path = QApplication::applicationFilePath();
        int index = path.lastIndexOf("/");
        path = path.mid(0, index);
        qDebug() << "applicationFilePath" << path;
        QDir dir;
        path=dir.currentPath();
        //qDebug() << "current path" << path;


        //构造新进程
        QProcess *updateProcess = new QProcess(this);

        //指定工作目录
        QString workingDir = "/home/mohanhui/work/tmp/test/qt5.3.2-64/softwareCenter/"
                "build-softwareCenter-Desktop_Qt_5_3_GCC_64bit-Debug" ;

        //指定可执行程序的路径
        QString program = workingDir +"/softwareCenterTest";

        /*1.setCurrent
         * 由子进程继承
         * 现象:由子进程继承了这个工作目录,子进程使用“./”即相当于这个setCurrent指定的目录,
         * 子进程读写文件使用"./"时,都在这个setCurrent指定的目录里面生效。
         * 但是子进程打印workingDirectory结果却是“”空的,不知道会不会有其他问题。
         */
    #if 0
        //更改父进程的工作目录
        QDir::setCurrent(workingDir);
        //启动新进程
        updateProcess->startDetached(program);
        qDebug() <<"新的工作目录" << updateProcess->workingDirectory();
        return;
    #endif
        
        /* 2.什么都不干
         * 现象:子进程打印workingDirectory是“”空的。子进程继承了父进程的工作目录,
         * 子进程使用“./”即相当于这个在父进程指定的目录,
         * 子进程读写文件使用"./"读写配置文件时,都在父进程的目录里面生效,所以子进程是不能正常工作的。
         */
    #if 0
        //启动新进程
        updateProcess->startDetached(program);
        qDebug() <<"新的工作目录" << updateProcess->workingDirectory();
        return;
    #endif
        
         /* 3.子进程启动前调用setWorkingDirectory
         * 现象:貌似用到相对路径的时候,程序会自己退出,原因不详。(可能和我的系统有关,
         * 没有在其他系统尝试)
         */
    #if 0
        //设置子进程工作目录
        updateProcess->setWorkingDirectory(workingDir);
        //启动新进程
        updateProcess->startDetached(program);
        qDebug() <<"新的工作目录" << updateProcess->workingDirectory();
        return;
    #endif
        
         /* 4.子进程创建时就指定工作目录,如newProcess->startDetached(program,QStringList(), workingDir);
         * 现象:很好,父进程与子进程的工作目录分开,互不影响。父进程使用相对目录
         * 时是相对父进程的工作目录,子进程使用相对路径时是相对子进程的工作目录。
         * */
    #if 0
        //启动新进程
        updateProcess->startDetached(program,QStringList(), workingDir);
        qDebug() <<"新的工作目录" << updateProcess->workingDirectory();
        return;
    #endif

    http://blog.csdn.net/u013281495/article/details/51086943

  • 相关阅读:
    Jmeter之http性能测试实战 非GUI模式压测 NON-GUI模式 结果解析TPS——干货(十一)
    UI Recorder 自动化测试 回归原理(九)
    UI Recorder 自动化测试 录制原理(八)
    UI Recorder 自动化测试 整体架构(七)
    UI Recorder 自动化测试 配置项(六)
    UI Recorder 自动化测试 工具栏使用(五)
    UI Recorder 自动化测试 回归测试(四)
    UI Recorder 自动化测试 录制(三)
    UI Recorder 自动化测试工具安装问题疑难杂症解决(二)
    UI Recorder 自动化测试安装教程(一)
  • 原文地址:https://www.cnblogs.com/findumars/p/5364744.html
Copyright © 2011-2022 走看看