I am trying to understand the consept of process. So I wrote a program like this:
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main() {
pid_t pid;
pid = fork();
if (pid == 0)
printf("This is the child process. My pid is %d and my parent's id is %d.\n", getpid(), getppid());
else
printf("This is the parent process. My pid is %d and my child's id is %d.\n", getpid(), pid);
}
I expected this program would print something like
This is the parent process. My pid is 2283 and my child's id is 2284.
This is the child process. My pid is 2284 and my parent's id is 2283.
But instead, it prints this
This is the parent process. My pid is 2283 and my child's id is 2284.
This is the child process. My pid is 2284 and my parent's id is 1086.
At the end of the second line, the parent pid of the child is different form the parent process's pid.
Why is this happening? Is there something that I am missing?
Thanks in advance
The hint of Tony Tannous was correct: The child may live longer than the parent. When the parent is exiting its child process is "hung up" i.e. it becomes child process of the init process.
I modified the sample code of OP to force the child process living longer then the parent process.
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
pid_t pid;
pid = fork();
if (pid == 0) {
sleep(1); /* 1 s */
printf(
"This is the child process."
" My pid is %d and my parent's id is %d.\n", getpid(), getppid());
} else {
printf(
"This is the parent process."
" My pid is %d and my child's id is %d.\n", getpid(), pid);
}
return 0;
}
Compiled and tested with gcc on cygwin:
$ gcc -o test-pid-ppid test-pid-ppid.c
$ ./test-pid-ppid
This is the parent process. My pid is 10748 and my child's id is 10300.
$ This is the child process. My pid is 10300 and my parent's id is 1.
In my test this is obvious due to the specific PID 1 (the PID the init process usually gets). I'm a little bit surprised about PID 1086 observed in the OP but:
There is no specification (I know) that init process must get PID 1 - its only usual.
The OP was run on a VM. There, may be, things are done slightly different than usual...
Concerning my belief that an exiting process would kill all of its children, I investigated further and found this: Is there any UNIX variant on which a child process dies with its parent?. In short: my belief was wrong. Thank's for that question which forced me to enlightment.
Related
I have the next code and I need to check the child process' status, but the sleep() confuses me. I think that the child becomes zombie for a period of time (until the parent finishes sleeping and waits). If this is correct, then what happens if the parent sleeps for 1 second instead of 1000? Will the child become orphan for a period of time? Or is the process finished correctly since the parent waits?
pid_t pid = fork();
if (pid) {
sleep(1000);
wait(NULL);
}
else {
sleep(5);
printf("Hello!");
}
"version:redis-3.0.2, file:rdb.c, method: int rdbSave(char * filename)", there're some UPDATE action to the global varaible "server":
server.dirty = 0;
server.lastsave = time(NULL);
server.lastbgsave_status = REDIS_OK;
I wonder, how can a child process update the varaible in father process? Theoretically, it can't.
rdbSave is run in the foreground in the main event loop thread, hence the update isn't done by a chile process.
Look at rdbSaveBackground for fork implementation.
I am aware that you can preform simple message passing with the following:
self() ! hello.
and you can see the message by calling:
flush().
I can also create simple processes in functions with something like:
spawn(module, function, args).
However I am not clear how one can send messages to the processes with out registering the Pid.
I have seen examples showing that you can pattern match against this in the shell to get the Pid assigned to a var, so if i create a gen_server such as:
...
start_link() ->
gen_server:start_link(?MODULE, init, []).
init(Pid) ->
{ok, Pid}.
...
I can then call it with the following from the shell:
{ok, Pid} = test_sup:start_link().
{ok,<0.143.0>}
> Pid ! test.
test
So my question is, can you send messages to Pids in the form <0.0.0> with out registering them to an atom or variable in the shell? Experimenting and searching as proved fruitless...
If you happen to need to send a message to a Pid based on the textual representation of its Pid, you can do (assuming the string is "<0.42.0>"):
list_to_pid("<0.42.0>") ! Message
This is almost only useful in the shell (where you can see the output of log messages or monitor data from something like Observer); any spawned process should normally be a child of some form of parent process to which it is linked (or monitored).
As for sending a message to something you just spawned, spawn returns a Pid, so you can assign it directly to a variable (which is not the same as registering it):
Pid = spawn(M, F, A),
Pid ! Message.
If you have the string "" to identify a pid, it is
either because you are working in the shell, and you use the representation you see, and you forgot to store this pid in a variable. Then simply use pid(X,Y,Z) to get it;
either because you did something like io_lib:format("~p",[Val]) where Val is the pid or a an erlang term which contain this pid. Then simply assign the pid to a variable (directly or extracting it from the term). It can be stored in an ets, send to another process without transformation
You should avoid to use the shell (or string) representation. One reason is that this representation is different when you ask the pid of one process from 2 different nodes as shown in the next screen capture.
I wanted to know what is kthread and why it does not take any memory and has no open files. I wrote some code which will simply print the PID of the currently running processes in a parent child tree format along with some additional information like used VMZ, RSS, threads, openfiles. All the children of the PID 2 named kthreadd did not have the VmSize and VmRSS in the /proc/[pid]/status file. the /proc/[pid]/fd did not contain any open files.
What are these processes, how they are different with normal processes spawned by init (PID 1). I read (in an old book) that the swapper will spawn init PID1 and all other process are children of PID 1. Definitely there is a different architecture behind this (Linux kernel 3.7.10.1-16) which I don't know, so another question is why PID 2 is a child of PID 0 and is not a child of PID 1 .
Kernel threads are not children of init because they can be started before all the userspace processes.
They are typically used to manage hardware that's why they are directly handled by the kernel and have high priority.
For a process to be child of init it needs to be cloned from init and Kthreads aren't that's why their parent PID is 0 meaning "no-one".
I'm writting a Perl script for which I need the uptime in seconds to do some calculation, in all the machine in the shop (i.e. linux, SunOS, and AIX). I have a way to get the uptime for linux (/proc/uptime), and SunOS (kstat -p unix:0:system_misc:boot_time), thanks to an another posting on this site, but I can find a good way of getting it for AIX. I don't really like the idea of parsing uptime with reg-ex, since uptime changes when the machine is been up just sec, mins, days, or over a year.
This snippet in C works under AIX 6.1.
I can't give you the source article as I only have source code left.
#include <utmpx.h>
int main ( )
{
int nBootTime = 0;
int nCurrentTime = time ( NULL );
struct utmpx * ent;
while ( ( ent = getutxent ( ) ) ) {
if ( !strcmp ( "system boot", ent->ut_line ) ) {
nBootTime = ent->ut_tv.tv_sec;
}
}
printf ( "System was booted %d seconds ago\n", nCurrentTime - nBootTime );
}
Parse the output of last(1)?
Find a file/directory that is only created/refreshed at boot time and stat it?
Frankly, using different regexs to handle the different possible outputs from uptime doesn't sound so bad.
Answering old thread for new interested stumblers.
We're going to make a lightweight C program called getProcStartTime that you'll have plenty of other uses for. It tells you when a process was started, given the PID. I believe you will still get a time stamp down to the second even if the process was started months or years ago. Save this source code as a file called getProcStartTime.c:
#include <time.h>
#include <procinfo.h>
main(argc, argv)
char *argv[];
{
struct procentry64 psinfo;
pid_t pid;
if (argc > 1) {
pid = atoi(argv[1]);
}
else {
printf("Usage : getProcStartTime pid\n");
return 1;
}
if (getprocs64(&psinfo, sizeof(struct procentry64), NULL, sizeof(struct fdsinfo64) , &pid, 1) > 0) {
time_t result;
result = psinfo.pi_start;
struct tm* brokentime = localtime(&result);
printf("%s", asctime(brokentime));
return 0;
} else {
perror("getproc64");
return 1;
}
}
Then compile it:
gcc getProcStartTime.c -o getProcStartTime
Here's the magic logic: AIX just like Linux has a process called init with PID 1. It can't be killed or restarted. So the start time of PID 1 is the boot time of your server.
./getProcStartTime 1
On my server, returns Wed Apr 23 10:33:30 2014; yours will be different.
Note, I originally made getProcStartTime specifically for this purpose, but now I use it in all kinds of other scripts. Want to know how long an Oracle database has been up? Find the PID of Oracle's PMON and pass that PID as your arg after getProcStartTime.
If you really want the output as an integer number of seconds, it would be an easy programming exercise to modify the code above. The name getProcUptime is just a suggestion. Then you could just call:
./getProcUptime 1
UPDATE: Source code and precompiled binary for AIX 6.1/7.1 have been put on my Github repo here: https://github.com/Josholith/getProcStartTime