1

I am creating a Qt/C++ console application which successfully forks. When I call QCoreApplication::applicationPid() before fork, and then after fork (in the child), I get the same pid.

I realize I could just use the return value from fork() but I'm trying to do things the Qt way. Is there a better/right way to get the PID of the child (from within the child) in Qt?

And out of curiosity, why isn't QCoreApplication::applicationPid() providing the new PID? I assume it's now providing the ppid....

TSG
  • 4,242
  • 9
  • 61
  • 121
  • You could use a `QThread` or `QConcurrent` instead of `fork`. `fork` is only on posix systems. http://en.wikipedia.org/wiki/Fork_(system_call) Also why can't you use the return value from `fork()`, like in the example on wikipedia? – phyatt Feb 02 '14 at 21:47
  • The return from fork does return the current process ID, BUT, I'm trying to do everything the Qt way...and Qt suggests the QCoreApplication::applicationPid() function. (Which doesn't work right for the child). I am creating a linux daemon so QThread is not a suitabile alternative to fork. (Nor QConcurrent I think) – TSG Feb 02 '14 at 22:22
  • Initially I was thinking in terms of threads. As far as cross platform process management, child processes, etc, the Qt way is to use `QProcess::start()` or `QProcess::startDetached()` instead of `fork()`... Then you could use `QProcess::pid ()`. But if you are only building for Linux, then it may not make sense to use the Qt way for launching a child process. – phyatt Feb 02 '14 at 23:15
  • Start() and startdetached() are for launching other programs...I am writing a service that must daemonize....so very different – TSG Feb 03 '14 at 02:46
  • when you use fork then you loose portability, so your insist on use of `QCoreApplication::applicationPid()` is irrational. Another thing [qt is open source](https://qt.gitorious.org/qt/qt/source/663b742ca8b289e6456facf8b6a8ca18a4157fb7:src/corelib/kernel/qcoreapplication.cpp#L2218) so you can always check why something disbehaves in qt when you mess with other low level API. – Marek R Feb 03 '14 at 09:45

1 Answers1

2

The return value of fork() depends whether you are in the fork or in the parent. See here:

On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.

Thus, you get the pid of the child only within the parent from fork() (not in the child as you seem to imply). That is actually how you check whether you are in the child or not -- i.e. whether the return value is 0 or not.

Anyway:

There is no way to fork the Qt way because forking is not possible on all platforms (esp. Windows), thus Qt cannot have that.

Also note that certain parts of Qt might be in an invalid state in the child (e.g. on MacOSX, the Cocoa GUI cannot be used in a forked process). So be careful.

I haven't really found details whether Qt otherwise supports forks (I mean in a way that it behaves sane: e.g. the list of threads in the fork will be different, so it must be aware of that). I have asked about that here.

QCoreApplication::applicationPid() probably caches the value and thus returns the wrong value in the child. But don't care about that, just use getpid() instead -- you are already using the non-cross-platform fork().

Community
  • 1
  • 1
Albert
  • 65,406
  • 61
  • 242
  • 386