I'm learning about the relationship between processes, process groups (and sessions) in Linux.
I compiled the following program...
#include <iostream>
#include <ctime>
#include <unistd.h>
int main( int argc, char* argv[] )
{
char buf[128];
time_t now;
struct tm* tm_now;
while ( true )
{
time( &now );
tm_now = localtime( &now );
strftime( buf, sizeof(buf), "%a, %d %b %Y %T %z", tm_now );
std::cout << buf << std::endl;
sleep(5);
}
return 0;
}
... to a.out
and ran it as a background process like so...
a.out &
This website says the following...
Every process is member of a unique process group, identified by its process group ID. (When the process is created, it becomes a member of the process group of its parent.) By convention, the process group ID of a process group equals the process ID of the first member of the process group, called the process group leader.
Per my reading, the first sentence conflicts with the in-parentheses content: is a process a member of a unique process group, or is it a member of the process group of its parent?
I tried to investigate with ps
...
ps xao pid,ppid,pgid,sid,command | grep "PGID\|a.out"
PID PPID PGID SID COMMAND
24714 23890 24714 23890 ./a.out
This tells me my a.out
process is pid 24714
, spawned from parent pid 23890
and part of program group 24714
. To begin with, I don't understand why this pgid matches the pid.
Next, I tried to investigate the parent process...
ps xao pid,ppid,pgid,sid,command | grep "PGID\|23890"
PID PPID PGID SID COMMAND
23890 11892 23890 23890 bash
24714 23890 24714 23890 ./a.out
It makes sense to me that the parent process of my a.out
is bash
. At first I thought "bash's pid matches its pgid - that must be because it's the process group leader. Maybe that makes sense because bash is kind of the "first thing" that got run, from which I ran my process." But that reasoning doesn't make sense because a.out
's pgid also matches its own pid.
Why doesn't a.out
's pgid equal bash
's pgid? That's what I would have expected, from my understanding of the quote.
Can someone clarify the relationship between pids and pgids?
fork
ing) of child process (pid 12676). Then bash callssetpgid
to set the pgid of the child process (12676) to 12676. But what's with the second call tosetpgid(12676, 12676)
that seems to be performed by process 12676? Then lastly, bashexecve
s the program to kick off the process. – StoneThrow May 04 '17 at 22:39setpgid
would be the reason whypg
's pgid doesn't match bash's pgid. As opposed to the parent/child processes from thepg
executable that demonstrate the "expected" behavior because there is no explicit call tosetpgid()
(?) – StoneThrow May 04 '17 at 22:42fork
(clone
, actually) not shown wherebash
splits into 12366 and 12676. The call complications aside, it's mostly to show thatbash
does not follow the expected behavior because it makes an extra system call. – thrig May 04 '17 at 22:48bash
puts the child into a new process group to implement job control. Each job has to be a separate process group from the shell so it can be moved from foreground to background. – Barmar May 05 '17 at 01:45