Results 1 to 9 of 9

Thread: Launching a process from a thread.

  1. #1
    Join Date
    Jun 2015
    Posts
    12
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Launching a process from a thread.

    I have to permorm a series of hard disk operations in the background, so the main gui should not freeze. All these operations I'm going to launch using QProcess, adding arguments to it as bash commands.
    Quite important thing to note is that a user has 2 options while these operations are going on in the background: 1) to quit the application 2) to stop the series of operations after the current operations is finished.

    What is the best strategy to build my app : 1) to create a thread and then create processes in it or 2) create processes without creating threads?

  2. #2
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Launching a process from a thread.

    What benefit does option #1 provide that option #2 doesn't? i.e. If the real work is done via a new process, then there is no benefit IMHO to create a separate thread in the first place, unless there's some other reason you didn't state above.

    My recommendation is to use the simplest design that meets your requirements. Threads are overused/misused by lots of people and serve no purpose other than to create hard to find bugs when not implemented properly.

    Hope that helps.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  3. #3
    Join Date
    Jun 2015
    Posts
    12
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Launching a process from a thread.

    I'm going to describe a little bit more in detail my situation.

    1)I have a container of widgets std::vector<QWidget*>container.
    2)Each widget has a method, let's call it launch_process(). It launches a process correspoindant to it's widget.
    3)The user presses start button and we have a loop: for(auto i : container) i->launch_process();
    4) I also must provide the user with posibility to stop the series of processes (the loop) after the current process is finished.
    5)So my idea was to write the loop this way : for(std::size_t i = 0; i < container.size() && !stop_pressed();++i) i->launch_process();
    6)When the user presses the stop button, he changes a private member stopped_;
    7) After the next launched process is terminated, stop_pressed() is called to check the state the private method stopped_ - if it's true - we're out of the loop.

    I've been choosing what to put inside launch_process() - 1) a thread and only then a process in it or 2) directly a process without threads.
    The main goal is to change stopped_ member while thread or process is "out there".
    Last edited by alexcodercpp; 6th August 2015 at 17:33.

  4. #4
    Join Date
    Oct 2009
    Posts
    483
    Thanked 96 Times in 93 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Launching a process from a thread.

    What does launch_process() do?

    From your description, it seems to start another process, then quickly return, leaving the process running in the background. No synchronization with the external process is done at this point. But then, you will never be fast enough to stop the loop. It will quickly start all the processes, which will all run concurrently with your program.

    I suggest you first explain what is supposed to run, when it is supposed to run (and what is supposed to run concurrently with what) before we help you work out a solution based on external processes, threads, high-level concurrent APIs, etc.

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,403
    Thanks
    37
    Thanked 1,542 Times in 1,493 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Launching a process from a thread.

    That sounds more like a job queue.

    - Check if you should stop, if yes, clear queue, done
    - Take the first job out of the queue
    - Connect job "finished" signal to some slot
    - Run that job
    - When the job signals it is done, continue at the beginning

    Cheers,
    _

  6. #6
    Join Date
    Jun 2015
    Posts
    12
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: Launching a process from a thread.

    To yeye_olive

    1) Inside each launch_process() will be launched simple bash command (I'm using linux) to perform disk operations.
    2) These launches should be consequential, in a loop, the next launches only and only when the previous is terminated.
    3) Each process does different job - one works with usb, another one with cd , third with hard disk and so on.
    4) Each process in the meantime should provide some feedback to the main GUI thread - like progress bar etc.

  7. #7
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Launching a process from a thread.

    Quote Originally Posted by alexcodercpp View Post
    I'm going to describe a little bit more in detail my situation.

    1)I have a container of widgets std::vector<QWidget*>container.
    2)Each widget has a method, let's call it launch_process(). It launches a process correspoindant to it's widget.
    3)The user presses start button and we have a loop: for(auto i : container) i->launch_process();
    4) I also must provide the user with posibility to stop the series of processes (the loop) after the current process is finished.
    5)So my idea was to write the loop this way : for(std::size_t i = 0; i < container.size() && !stop_pressed();++i) i->launch_process();
    6)When the user presses the stop button, he changes a private member stopped_;
    7) After the next launched process is terminated, stop_pressed() is called to check the state the private method stopped_ - if it's true - we're out of the loop.

    I've been choosing what to put inside launch_process() - 1) a thread and only then a process in it or 2) directly a process without threads.
    The main goal is to change stopped_ member while thread or process is "out there".
    I assume your processes will be writing output to stdout or stderr that indicate their progress, which you can readily consume by hooking up the QProcess::readyReadStandardError() or QProcess:readyReadStandardOutput(). That said, I believe you will need to use QProcess::startDetached() due to your requirement that the user can exit your app while the processes are still running. In that case, your app would need to start the processes and redirect their stdout/stderr to files, which can then be opened and read by your application, etc.

    As far as stopping the running processes, you can use QProcess::terminate() but I would caution you about killing running processes if they are modifying data or changing disk metadata, etc. You may also find instances where you need to use a bigger hammer to terminate a running QProcess, requiring an OS specific technique.

    Your GUI will be unresponsive while you loop through your container starting QProcess's. You didn't indicate how many Widgets in your container, if a small number (subjective), then I don't believe a separate thread would be of any benefit. If you have a large (subjective) number of widgets to loop through, then you may find it desirable to use a thread and then emit a signal in your GUI thread that sends the info to your thread and start the QProcess, etc. You could also add a call to QApplication::processEvents() to your loop that should keep your GUI responsive.

    If you do decide to launch the QProcesses using a separate thread, I would recommend that you use QtConcurrent::run() to run your launch_process() in a separate thread as opposed to sub-classing QThread or the other "Move To Thread" approach (Google it).

    Hope that helps.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  8. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,403
    Thanks
    37
    Thanked 1,542 Times in 1,493 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Launching a process from a thread.

    Quote Originally Posted by jefftee View Post
    That said, I believe you will need to use QProcess::startDetached() due to your requirement that the user can exit your app while the processes are still running.
    Instead of losing control over the process, I would recommend to keep the application running instead, but just close all its windows.

    So there won't be any difference between normal operation and "user closes app but wants all jobs to continue".

    Quote Originally Posted by jefftee View Post
    Your GUI will be unresponsive while you loop through your container starting QProcess's
    If I understood correctly, there won't be any explicit loop.
    The job sequence only runs one job after the previous one has finished, so there is always only one job running any given time.

    Cheers,
    _

  9. #9
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: Launching a process from a thread.

    Quote Originally Posted by anda_skoa View Post
    Instead of losing control over the process, I would recommend to keep the application running instead, but just close all its windows.

    So there won't be any difference between normal operation and "user closes app but wants all jobs to continue".
    _
    I would also agree that would be my approach, however, since the app could crash or be closed for some other reason, I think the OP should still design some type of persistent process status into his app so that his app can keep track of the tasks status whether or not his app remains running.

    Quote Originally Posted by anda_skoa View Post
    If I understood correctly, there won't be any explicit loop.
    The job sequence only runs one job after the previous one has finished, so there is always only one job running any given time.
    _
    Agreed, I only suggested the potential need for this based on the for loop he described in #5 of the OP's detailed description. I have no idea what the will be done in the for loop, so it may not require any special consideration.

    Thanks
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

Similar Threads

  1. Replies: 1
    Last Post: 16th April 2014, 07:44
  2. Launching QThreads from a loop
    By lynchkp in forum Qt Programming
    Replies: 3
    Last Post: 9th September 2012, 11:37
  3. Handler thread to process messages asynchronously
    By Luc4 in forum Qt Programming
    Replies: 5
    Last Post: 24th April 2011, 15:07
  4. Launching problem
    By Salazaar in forum Newbie
    Replies: 5
    Last Post: 29th October 2007, 11:18
  5. GUI Thread getting no time to process
    By steg90 in forum Qt Programming
    Replies: 11
    Last Post: 9th May 2007, 09:29

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.