printing child variable values in linux
In linux I have a parent and a child process. I want to manipulate the variables I pass to the child process and then print them on the screen. How do I go about printing child pr开发者_StackOverflow中文版ocess values.
If you mean manipulate the child process variables from the parent, forget about it.
Barring some well-implemented inter-process communication (IPC) or some kludgy "use root to read/write other-process memory", it's not the done thing.
Processes maintain their own memory spaces and do not interfere with each other - there are ways to share memory between processes but you generally have to work at it: a simple fork will not give you that.
If you mean from the child, well, the child has full access to all its variables. Just use and/or modify them as you wish, but that won't change their values in the parent. If you want to communicate changes back to the parent, again you'll have to use some sort of IPC mechanism (or even an equivalent like the return code or using a file for information transfer).
You can see how the processes get their own copies of the variables here:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
int main (void) {
int i, val = 100;
switch (fork()) {
case -1: { // Couldn't fork, just output error.
printf ("Could not fork, error = %d\n", errno);
break;
}
case 0: { // I am the child, increase val at t=1,3,5,7,...
sleep (1);
for (i = 0; i < 5; i++) {
val++;
printf ("Child: val = %d\n", val);
sleep (2);
}
break;
}
default: { // I am the parent, decrease val at t=0,2,4,6,...
for (i = 0; i < 5; i++) {
val--;
printf ("Parent: val = %d\n", val);
sleep (2);
}
break;
}
}
return 0;
}
This code outputs:
Parent: val = 99
Child: val = 101
Parent: val = 98
Child: val = 102
Parent: val = 97
Child: val = 103
Parent: val = 96
Child: val = 104
Parent: val = 95
Child: val = 105
showing that the val
variable is distinct for the two processes. If it were shared, you would expect to see 99, 100, 99, 100, 99, 100, ...
.
Here is one way I apply for a similar need, but I have no idea if it's matching your question, as it's somewhere next to the grey zone I guess:
You could achieve this in a single bash shell, let's say you define parent/child commands and associate a pid to each parent command, then you can do whatever you need once you have associated both parent/child together. But "by hand". For example the parent command can store any kind of variable/file you need, and you can get/read it back with the child process when started (assuming there are no other process modiyfing them.. quite hazardous hum, so in that case, better keeping all data in the same nut) :
Take care, this code is only to illustrate my above answer, but not working out of the box :
# define your parent/child commands
for directory in "${SVN_PROJECTS_DIR[@]}"
do
# array push
PARENT_CMD=( "${PARENT_CMD[@]}" "$parent_cmd" )
CHILD_CMD=( "${CHILD_CMD[@]}" "$child_cmd" )
done
# Run the parent commands and associate a child command to the parent pid
for (( index = 0 ; index < ${#PARENT_CMD[@]} ; index++ ))
do
# Run the parent cmd
(eval "${PARENT_CMD[$index]}") &
# Store the parent pid into a specific array
# we actually need the pid only but all parent pids will be needed at the next stage
PARENT_PID=( "${PARENT_PID[@]}" "$!" )
# Associate the child cmd to the parent pid
CHILD_CMD_[$!]="${CHILD_CMD[index]}"
done
# Then RUN CHILD THREADS when parent pid's end
while :; do
# Scan running parent pid's
for pid in "${PARENT_PID[@]}"
do
# Gracefully closed parent pid => run child pid
if wait "$pid"; then
# start child pid IF parent_pid was not already tagged as starting a child
in_array "${pid}" "${TAGGED_PARENT_PID[@]}"
RET=$?
# if RET=1 => parent pid was not in tagged pid's array
if [ "${RET}" -eq 1 ] ;then
# Run child process (if it was not already started)
(eval "${CHILD_CMD_[$pid]}") &
RET=$?
# Abort on error (do not want to global track this)
[[ "X$RET" != "X0" ]] && (( errors++ )) && exit 1
# Store the parent pid in TAGGED_PARENT_PID array sothat you know if a child process has been started for the corresponding parent pid
TAGGED_PARENT_PID=( "${TAGGED_PARENT_PID[@]}" "$pid" )
# Store also the child pid in child_pid array
CHILD_PID=( "${CHILD_PID[@]}" "$!" )
echo "=> $! child pid has been started"
echo "=> cmd: ${CHILD_CMD_[$pid]}"
# Trac started children processes for further treatments
(( started_children++ ))
fi
# Errored parent pid (bad exit code)
else
# assuming you've checked elsewhere that parent's pid is not still alive
echo "parent pid ended with a bad exit status code"
(( errors++ ))
fi
done # end FOR
# GRACEFUL EXIT CONDITIONS
# COND 1: WHILE exit if all children have been effectively started
[[ "$started_children" -eq "${#CHILD_CMD[@]}" ]] && echo "All children processes have been started" && break
# COND 2: blabla
# BAD EXIT CONDITIONS
# you have to plan them, like timeout or error exits
done # end WHILE
# At this stage, your parent processes are finished (gracefully) and your children processes have been started. So you could get whatever variable or file you need, making sure they are inherited from the parent process. You can also use locked files to ensure no other process(es) are touching your parent file.
I hope that might help you to start or give you ideas to succeed in doing that you need.
精彩评论