If I have an executable, what is the correct way to run it twice with shell script ?
The process to be executed twice is using shared memory for message passing and shared semaphores
using simply
./a
./a
will run one process and other process can't run until first process stops and therefore no communication between two processes takes place
what is the right way to run one executable twice in parallel fashion ?
As #SamVarshavchik said, use an ampersand to run a process in the background, so the other one can run concurrently:
./a &
./a
or
./a & ./a
If, as your comments imply, the second process needs to be in the background because the first process is interactive, you can do:
{ sleep 10; ./second; } &
./first
Alternatively, you can start each process with its own Terminal:
xterm -e "./first" &
xterm -e "./second" &
At first, instead of bash hacking, it would be better to rewrite your app and make it fork() on start. But in general, if you want to bring the first process to foreground you can use an fg command:
./a &
./a &
fg 1
Related
I'm using perf for profiling on Ubuntu 20.04 (though I can use any other free tool). It allows to pass a delay in CLI, so that event collection starts after a certain time since program launch. However, this time varies a lot (by 20 seconds out of 1000) and there are tail computations which I am not interested in either.
So it would be great to call some API from my program to start perf event collection for the fragment of code I'm interested in, and then stop collection after the code finishes.
It's not really an option to run the code in a loop because there is a ~30 seconds initialization phase and 10 seconds measurement phase and I'm only interested in the latter.
There is an inter-process communication mechanism to achieve this between the program being profiled (or a controlling process) and the perf process: Use the --control option in the format --control=fifo:ctl-fifo[,ack-fifo] or --control=fd:ctl-fd[,ack-fd] as discussed in the perf-stat(1) manpage. This option specifies either a pair of pathnames of FIFO files (named pipes) or a pair of file descriptors. The first file is used for issuing commands to enable or disable all events in any perf process that is listening to the same file. The second file, which is optional, is used to check with perf when it has actually executed the command.
There is an example in the manpage that shows how to use this option to control a perf process from a bash script, which you can easily translate to C/C++:
ctl_dir=/tmp/
ctl_fifo=${ctl_dir}perf_ctl.fifo
test -p ${ctl_fifo} && unlink ${ctl_fifo}
mkfifo ${ctl_fifo}
exec ${ctl_fd}<>${ctl_fifo} # open for read+write as specified FD
This first checks the file /tmp/perf_ctl.fifo, if exists, is a named pipe and only then it deletes it. It's not a problem if the file doesn't exist, but if it exists and it's not a named pipe, the file should not be deleted and mkfifo should fail instead. The mkfifo creates a named pipe with the pathname /tmp/perf_ctl.fifo. The next command then opens the file with read/write permissions and assigns the file descriptor to ctl_fd. The equivalent syscalls are fstat, unlink, mkfifo, and open. Note that the named pipe will be written to by the shell script (controlling process) or the process being profiled and will be read from the perf process. The same commands are repeated for the second named pipe, ctl_fd_ack, which will be used to receive acknowledgements from perf.
perf stat -D -1 -e cpu-cycles -a -I 1000 \
--control fd:${ctl_fd},${ctl_fd_ack} \
-- sleep 30 &
perf_pid=$!
This forks the current process and runs the perf stat program in the child process, which inherits the same file descriptors. The -D -1 option tells perf to start with all events disabled. You probably need to change the perf options as follows:
perf stat -D -1 -e <your event list> --control fd:${ctl_fd},${ctl_fd_ack} -p pid
In this case, the program to be profiled is the the same as the controlling process, so tell perf to profile your already running program using -p. The equivalent syscalls are fork followed by execv in the child process.
sleep 5 && echo 'enable' >&${ctl_fd} && read -u ${ctl_fd_ack} e1 && echo "enabled(${e1})"
sleep 10 && echo 'disable' >&${ctl_fd} && read -u ${ctl_fd_ack} d1 && echo "disabled(${d1})"
The example script sleeps for about 5 seconds, writes 'enable' to the ctl_fd pipe, and then checks the response from perf to ensure that the events have been enabled before proceeding to disable the events after about 10 seconds. The equivalent syscalls are write and read.
The rest of the script deletes the file descriptors and the pipe files.
Putting it all together now, your program should look like this:
/* PART 1
Initialization code.
*/
/* PART 2
Create named pipes and fds.
Fork perf with disabled events.
perf is running now but nothing is being measured.
You can redirect perf output to a file if you wish.
*/
/* PART 3
Enable events.
*/
/* PART 4
The code you want to profile goes here.
*/
/* PART 5
Disable events.
perf is still running but nothing is being measured.
*/
/* PART 6
Cleanup.
Let this process terminate, which would cause the perf process to terminate as well.
Alternatively, use `kill(pid, SIGINT)` to gracefully kill perf.
perf stat outputs the results when it terminates.
*/
According to my purpose, I just want to let my process be running in the background. Then I could write normal program and run it with the following command:
nohup myprogram 1>2 2>/dev/null &
Then this program will be running in the background, just like as a daemon.
With this way, I do not need to call fork() for running in background.
So my question is what is the difference to run program in background with the above command between using fork() function?
TL;DR the fork() call is not needed, it just helps providing a nice UI for the users of the program.
A daemon uses fork() to create a duplicate of it. The child process then keeps running (in the background). The parent process may produce some output (status) then it exits.
Of course you can write only the child part of the program and launch it using the command line you posted:
$ nohup myprogram 1>2 2>/dev/null &
But if you write the daemon and I have to use it, I certainly prefer to use a simpler command line, without all that scaffolding needed to put the program in background and ensure its output doesn't make it stop and so on:
$ myprogram # there is no need for anything else
I was trying to run netcat by using ssh and seems that my code always fails in my C code. Here are the commands which I am executing using system() in this order.
system("ssh machine 'nc -l 61001|dd bs=64M of=temp' &")
system("/bin/dd if=filename bs=64M|nc IP_address 61001")
I noticed that the first command works correctly as the temp file is created on the remote machine. The second dd command fails and states that 0 bytes has been written on the remote machine. These commands work correctly when executed from the terminal, but fail as soon as I put it in system() calls in C.
Short answer:
a & disown (instead of just &) should do.
Explanation:
system() spawns a shell that just executes one command and then exits. The & tells the shell to fork the command into background (means, it doesn't wait for its completion), but it's still part of the session and process group of the shell. When the group leader (the shell) exits, all children are killed. The disown causes the shell to start new process group, the child process is now owned by init (the first process in the system).
"Real" answer:
This is about programming. You are forking processes like crazy to accomplish something a C program could easily do using builtin library calls (except for the ssh but there are better ways, too). Go read on BSD sockets.
For example,if i use system() command from a c program to invoke a shell command whether it will complete the shell command and then it'll proceed with program or it'll do both concurrently
what are all the various methods available to find this information ?
You can use fork() or exec() for non-blocking, but a system() call is blocking. This means it will wait for your shell command to finish prior to resuming executing of your C program.
Note if you want it to return right away, you can issue your system command with an & behind it and your C program will run concurrently.
Sequential Example:
system("long_script.sh");
Concurrent Example:
system("long_script.sh &");
In a Linux/C++ library I'm launching a process via the system() call,
system("nohup processName > /dev/null&");
This seems to work fine with a simple test application that exits on it's own, but if I use this from inside of a Nodejs/V8 extension which gets a kill signal, the child process gets killed. I did find that running,
system("sudo nohup processName > /dev/null&");
With the sudoers file set up to not require a password manages to make this run even when the parent process (node) exits. Is there someway to entirely detach the child process so signals sent to the parent and the parent exiting have no effect on the child anymore? Preferably within the system() call and not something that requires getting the process ID and doing something with it.
The procedure to detach from the parent process is simple: Run the command under setsid (so it starts in a new session), redirecting standard input, output and error to /dev/null (or somewhere else, as appropriate), in background of a subshell. Because system() starts a new shell, it is equivalent to such a subshell, so
system("setsid COMMAND </dev/null >/dev/null 2>/dev/null &");
does exactly what is needed. In a shell script, the equivalent is
( setsid COMMAND </dev/null >/dev/null 2>/dev/null & )
(Shell scripts need a subshell, because otherwise the COMMAND would be under job control for the current shell. That is not important when using system(), because it starts a new shell just for the command anyway; the shell will exit when the command exits.)
The redirections are necessary to make sure the COMMAND has no open descriptors to the current terminal. (When the terminal closes, a TERM signal is sent to all such processes.) This means standard input, standard output, and standard error all must be redirected. The above redirections work in both Bash and POSIX shells, but might not work in ancient versions of /bin/sh. In particular, it should work in all Linux distros.
setsid starts a new session; the COMMAND becoming the process group leader for its own process group. Signals can be directed to either a single process, or to all processes in a process group. Termination signals are usually sent to entire process groups (since an application may technically consist of multiple related processes). Starting a new session makes sure COMMAND does not get killed if the process group the parent proces belongs to is killed by a process-group wide signal.
My guess is that the whole process group is being killed. You could try setpgid in the child to start a new process group. The first step should be to get rid of system and use fork and execve or posix_spawn.