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

  • 相关阅读:
    帝国cms在任意位置调用指定id的栏目名称和链接
    Sublime Text 2中前端必备的常用插件
    sublime text 2代码片段(Snippet)功能的使用
    写好PPT的四大要点
    解码郭台铭语录,50句你应该知道的“郭台铭语录”
    java.sql.SQLSyntaxErrorException: Table 'demo.hibernate_sequence' doesn't exist
    Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.example.demo.domain.DeptInfo
    com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver的区别
    Spring Boot引入Lombok
    Spring Boot(二)jpa操作数据库
  • 原文地址:https://www.cnblogs.com/findumars/p/5364744.html
Copyright © 2011-2022 走看看