Is there a way to stop and resume a C program - c

I am doing a project in C and in that I need to process a lot of data . Is there a way to stop the program automatically after 30 minutes and then resume whenever I run the program again?

There is no automatic way to do this. If you're on a Unix system though, you can press Ctrl+Z while your program is running to send it a STOP signal. It will wait until you continue again by sending it a CONT signal (the easiest way is with the fg shell command). A stopped process is still resident in memory, but is not running.
There are more sophisticated ways to take a "snapshot" of a running program and save it to disk. Later, you can load the snapshot and continue execution of the program. For example, see CryoPID.

You could automate it. The Crtl-Z and fg are, as already mentioned, nothing more than signals. In Unixes you can send them with the kill command. So kill -19 $PID will stop your process (when $PID is its PID) and kill -18 will continue it.
You just have to write a wrapper script, that looks like:
#!/bin/sh
PIDFILE=wherever/myprogram.pid
if [ -e $PIDFILE ]; then
kill -18 `cat $PIDFILE`
else
myprogram &
echo $! > $PIDFILE
fi
sleep 30
kill -19 `cat $PIDFILE`
(very short, untested, you have to take care to remove the pidfile when you kill the process). First time you run it, it will start the execution (for 30 seconds), the later times it will just revoke your program. You could improve it e.g by checking in the beginning if there is a process of your program in the process list, and if not remove the pidfile in case it is already there. So it would even behave correct after reboot or termination of your process.

Short answer: Without putting in some effort to have your program 'hibernate itself', no.
If you're running on UNIX then I'm sure you can set up a cron job to suspend / resume the program as and when needed. Under Windows you'll be afforded no such luxury.

Related

How to wait for multiple instance of one program to complete in linux?

How can I wait for multiple instance of same program to finish ? Below is my scenario any suggestion or pointers ?
I need to restart a running C process. After googling for long time, I figured out restarting can only done by fork and exec(I need the new instance to have a different pid than the original one hence using only exec wont work). Below is the sequence i did.
Shell 1:
Bash script
1. Start the first instance(./test.exe lets say pid 100)
2. Wait for it complete(pid 100) <<< Here need to wait for all instances of test.exe to complete
Shell 2:
1. Send a signal to above process(pid-100)
2. In signal handler had fork(new pid 200) a new process with exec command(./test.exe --restart) and kill parent (pid 100)
Now my question is that how can wait for all instances of test.exe to complete in shell1's bash script ?(basically have to wait until pid 200 is completed)
With my current approach shell1's bash script exits as soon as I send signal to kill pid 100
Update:
Actually I am looking for some bash/unix command to wait for all instances of test.exe is finished. Something like - 'wait $(pgrep -f test.exe)'
Basically you are looking for inter-process synchronisation mechanisms, i.e. inter-process semaphores and inter-process mutexes.
Two approaches that come to mind are POSIX semaphores and the older System V semaphores. I would recommend the former.
Also check out this SO reply.
Hope this helps :)

C programming basic shell

I am trying to write a simple shell which accepts command line input and execute it as a background task.
How do I allow the child process to report to the parent process once it is completed, like the Bash shell?
user#user-desktop:~$ sleep 10 &
[1] 3729
user#user-desktop:~$ sleep 2 &
[2] 3730
user#user-desktop:~$
[1]- Done sleep 10
[2]+ Done sleep 2
Since this is your homework, I won't give you full answer.
The GNU Glibc manual list the requirnment for job control shell. Let's see if you can understand it.
Basically:
you have to change the control terminal to make jobs run in background
you have to handle SIGCHLD (or wait) to monitor jobs
Ask again after you have read it.
You need to code a signal handler that handles the SIGCHLD (sometimes named SIGCLD) signal which is sent to parent processes when a child terminates.

Running program in background

Ive got my program in C, 6 source files, and the aim is to copy those files to any other Linux OS computer, and (probably compile, im newbie, so not sure what is needed here) run this program in background. Something like:
user#laptop:~$ program
Program is running in a background. In order to stop Program, type
XXX.
Any tips on this?
Thanks in advance!
Put a daemon(0,0); call in your C program.
stopping it is a bit trickier, I suppose there is only one copy of the program running. Put the program's PID in a file, write another utility (XXX) which reads the PID from the file and kills it.
Important: daemon forks, get the PID of the program after calling daemon.
But maybe you are too newby and just want to execute your program with program& and later kill it.
I completely missunderstood the question. You need shell scripting for this.
For file copying you can use scp. Execute command on the other host with ssh. It should be something like (not tested):
pid=`ssh user#host "make >/dev/null 2>&1; nohup ./program; echo $!`
later you can stop it with
ssh user#host "kill $pid"
First, you should fork().
In parent, you should just exit, in child process - you should handle SIGHUP signal.
In such way - you have daemon.

create process independent of bash

I have written a program which calculates the amount of battery level available in my laptop. I have also defined a threshold value in the program. Whenever the battery level falls below threshold i would like to call another process. I have used system("./invoke.o") where invoke.o is the program that i have to run. I am running a script which runs the battery level checker program for every 5 seconds. Everything is working fine but when i close the bash shell the automatic invocation of invoke.o is not happening. How should i make the invoke.o to be invoked irrespective of whether bash is closed or not??. I am using UBUNTU LINUX
Try running it as: nohup ./myscript.sh, where the nohup command allows you to close the shell without terminating the process.
You could run your script as a cron job. This lets cron set up standard input and output for you, reschedule the job, and it will send you email if it fails.
The alternative is to run a script in the background with all input and output, including standard error output, redirected.
While you could make a proper daemon out of your program that kind of effort is probably not necessary.
man nohup
man upstart
man 2 setsid (more complex, leads to longer trail of breadcrumbs on daemon launching).

How do I know if an C program's executable is run in foreground or background?

In my C program I want to know if my executable is run in foreground like this
$./a.out
or like this
$./a.out &
If you are the foreground job,
getpgrp() == tcgetpgrp(STDOUT_FILENO)
or STDIN_FILENO or STDERR_FILENO or whichever file descriptor you're attached to your controlling terminal by. (If you're not sure, open("/dev/tty") will always get you a file descriptor to your controlling terminal, if one exists.)
This is what openssh does, and is a bit easier than handling SIGTTIN/SIGTTOU if you just want a quick check.
On the other hand, you may have been backgrounded
$ ./a.out
^Z
[1]+ Stopped ./a.out
$ bg
[1]+ ./a.out &
or foregrounded
$ fg
./a.out
at any point in time. You cannot expect that you can check this once and it will still be true (or false) later.
From the Bash Reference Manual: Job Control Basics:
Background processes are those whose process group id differs from the terminal's; such processes are immune to keyboard-generated signals. Only foreground processes are allowed to read from or write to the terminal. Background processes which attempt to read from (write to) the terminal are sent a SIGTTIN (SIGTTOU) signal by the terminal driver, which, unless caught, suspends the process.
So the solution is to install a signal handler for SIGTTIN and then try to read from stdin (turn buffering off or it will block). If you get "0 bytes read" back, then you're running in the foreground.
[EDIT] Note that the status of a process can change. You can use the job control commands of the shell (Ctrl-Z, bg, fg and jobs) to do this.
To my knowledge this is not possible and usually not necessary either.
Please explain why you want to do this.
[invalid]IIRC, getppid() (on *nix systems) will give you the parent id. if it is 0, the 'console' is your parent and so you are running in the background.
[/invalid]
[edit]
int devtty;
if ((devtty = open ("/dev/tty", O_RDWR)) < 0)
printf ("daemon\n");
note that this is only valid on *nix systems (and then only if nobody has deleted /dev/tty -- for whatever reason)
[/edit]
There may be a possibility that you have more than one process
running in the background:
$ jobs
[1] Stopped teamviewer
[2]- Stopped vim
[3]+ Stopped firefox
use: fg %2 to send the vim process back to foreground.
To send the last process back to foreground simply use: fg with no
arguments.
You can also type % process_name to resume the stopped process.
To suspend the process running in the background, use:
kill -19 %job_id.
The -19 signal is SIGSTOP (the signal sent by Ctrl - Z) .
you can always see the list by typing kill -l
Moving jobs between background / foreground:
If you have already typed a command and forgot to use the &, you can put a foreground job into the background by typing ^Z (CTRL-Z) to suspend the job, followed by bg, to put it into the background:
$ sleep 99
^Z
[1]+ Stopped sleep 99
$ bg
[1]+ sleep 99 &
You can list the jobs of the current shell using the jobs command.
Just remember that "exiting shell" affects jobs as well:
Jobs running in the background when the shell exits are left running.
Jobs that are paused (“Stopped”) when the shell exits are terminated.
Sending signals to jobs and processes
You can send signals, including termination signals, to jobs that are started from the current shell using job numbers using %(JOBID) instead of process numbers(PID):
$ kill %1
[1]+ Terminated sleep 99
To send signals to processes or jobs that are not started from the current shell, you first need to use ps to find their process numbers(PID).
You can refer to this link:
processes and jobs
The general job control commands in Linux are:
jobs - list the current jobs
fg - resume the job that's next in the queue
fg %[number] - resume job [number]
bg - Push the next job in the queue into the background
bg %[number] - Push the job [number] into the background
kill %[number] - Kill the job numbered [number]
kill -[signal] %[number] - Send the signal [signal] to job number [number]
disown %[number] - disown the process(no more terminal will be owner), so command will be alive even after closing the terminal.
That's pretty much all of them. Note the % infront of the job number in the commands - this is what tells kill you're talking about jobs and not processes.

Resources