kill process after certain seconds.

S

SamuelXiao

Hi, I want to stop a process after given certain seconds, I do some
search but cannot find satisfied method. The follow is my function.

void calculate()
{
time_t seconds;
int num1,num2;
int ans,userans;

do{
time(&seconds);
srand((unsigned int) seconds);
num1 = rand() % 100;
num2 = rand() % 100;
ans = num1 + num2;
printf("please input the answer of %d + %d = \n",&num1,&num2);
scanf("%d",&userans);
if(userans!=ans){
printf("Sorry, Wrong,the correct answer is %d\n",&ans);
}
else{
printf("Correct, you are really clever.");
}
printf("Input negative number to terminate");
}while(input>0)
}

My program is to calculate whether the user's input is correct with
the computer-calculated answer. At the same time, I want to do a more
thing. It is that if the user do nothing or do after a certain
seconds (e.g. 4 seconds), the program will be ended automatically.
Any suggestions and help would be appreciated.
 
N

Nate Eldredge

SamuelXiao said:
Hi, I want to stop a process after given certain seconds, I do some
search but cannot find satisfied method. The follow is my function.

void calculate()
{
time_t seconds;
int num1,num2;
int ans,userans;

do{
time(&seconds);
srand((unsigned int) seconds);
num1 = rand() % 100;
num2 = rand() % 100;
ans = num1 + num2;
printf("please input the answer of %d + %d = \n",&num1,&num2);
scanf("%d",&userans);
if(userans!=ans){
printf("Sorry, Wrong,the correct answer is %d\n",&ans);
}
else{
printf("Correct, you are really clever.");
}
printf("Input negative number to terminate");
}while(input>0)
}

My program is to calculate whether the user's input is correct with
the computer-calculated answer. At the same time, I want to do a more
thing. It is that if the user do nothing or do after a certain
seconds (e.g. 4 seconds), the program will be ended automatically.
Any suggestions and help would be appreciated.

There isn't a way to do this in ISO Standard C. But many systems
provide a function called alarm(), which raises a signal after a
specified time. If you don't handle the signal (using the signal() or
sigaction() functions), your program gets killed, though not very
gracefully.
 
S

SamuelXiao

There is an easy way and a hard way to do this, depending on your
requirements:

Easy: Wait forever until the user provides an answer.  Upon receiving
user input, calculate the amount of time that has passed.  End the
program if this amount of time is too great.

Hard: Wait until either: a) the user provides an answer, or b) 4
seconds pass - whichever comes first.  If 4 seconds pass before the
user provides an answer, then automatically end the program.

From reading your request, I believe you only need the easy way. I
have inserted comments in your code below that explain how to
accomplish this.



                // 1. Get the current time here and store it in an
                // additional time_t variable.
                // 2. Calculate the difference between the two time_t
                // variables (e.g., "diff")
                // 3. if diff > 4 seconds, then end the
                // program
                // 4. else, proceed to parse answer


The idea is to order your "if" statements by priority.  When the user
answers the question, the first thing you care about is how much time
has passed, so check the time before parsing the response.


Nate Eldredge,throatslasher, Thanks for your help , I am now using
this way:

int times_up();

void calculate(int tchildlschild)
{
time_t seconds;
int num1,num2;
int ans,userans;
int input;

printf("Start the game");
signal(SIGALRM,times_up);
alarm(tchildlschild);
do{
clock_t start = clock();
time(&seconds);
srand((unsigned int) seconds);
num1 = rand() % 100;
num2 = rand() % 100;
ans = num1 + num2;
printf("please input the answer of %d + %d = \n",&num1,&num2);
scanf("%d",&userans);
if(userans!=ans){
printf("Sorry, Wrong,the correct answer is %d\n",&ans);
}
else{
printf("Correct, you are really clever.");
}
printf("Input negative number to terminate");
}while(input>0);
}

int times_up(sig)
int sig;
{
printf("Caught signal #< %d >\n",sig);
printf("Time's up!\n");
exit(sig);
}

I haven't checked it. By the way, I have tried extra way:

time_t t1,t2,t3;

(void)time(&t1);
sleep(5);
(void) time(&t2);
printf("\n%d",t1);
printf("\nFirst child process is executed after %d seconds\n",(int)
t2-t1);

But (int) t2-t1 has nothing output. What is wrong with it?
 
N

Nate Eldredge

SamuelXiao said:
Nate Eldredge,throatslasher, Thanks for your help , I am now using
this way:

int times_up();

Why not use a prototype?

int times_up(int);
void calculate(int tchildlschild)
{
time_t seconds;
int num1,num2;
int ans,userans;
int input;

printf("Start the game");
signal(SIGALRM,times_up);
alarm(tchildlschild);
do{
clock_t start = clock();
time(&seconds);
srand((unsigned int) seconds);
num1 = rand() % 100;
num2 = rand() % 100;
ans = num1 + num2;
printf("please input the answer of %d + %d = \n",&num1,&num2);
scanf("%d",&userans);
if(userans!=ans){
printf("Sorry, Wrong,the correct answer is %d\n",&ans);
}
else{
printf("Correct, you are really clever.");
}
printf("Input negative number to terminate");
}while(input>0);
}

int times_up(sig)
int sig;

Similarly, here use

int times_up(int sig)
{
printf("Caught signal #< %d >\n",sig);
printf("Time's up!\n");
exit(sig);
}

That's approximately the right idea. However, you should not call
printf from a signal handler. The handler times_up might run while
scanf is in the middle of executing, and on many systems that will cause
it to break (printf and scanf may share some resources).

It is better to arrange for the handler to set a flag that the main
program checks, but there are some subtleties. At this point things
start to get more system-specific. It would probably be better to
discuss this on a group for your system. If it's Unix, for instance,
comp.unix.programmer would be good.
 
K

Kojak

Le Tue, 17 Mar 2009 20:38:04 -0700 (PDT),
SamuelXiao a écrit :
Hi, I want to stop a process after given certain seconds, I do some
search but cannot find satisfied method. The follow is my function.

void calculate()
{
[... sniped ...]
}

My program is to calculate whether the user's input is correct with
the computer-calculated answer. At the same time, I want to do a more
thing. It is that if the user do nothing or do after a certain
seconds (e.g. 4 seconds), the program will be ended automatically.
Any suggestions and help would be appreciated.

<OT>

Even though you've already get answers, you can try another way of
doing what you are looking for using POSIX threads.

That said, this is just for the fun. Here is an example, not very
clean, but working enough to show the idea:

---8<------8<------8<------8<------8<------8<------8<------8<---
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <signal.h>

#define MAXTIME 4

int reading = 1;
int userans;

void get_answer (void)
{
int nil;
while (!scanf ("%d", &userans))
while (((nil = getchar ()) != '\n') && nil != EOF);
reading = 0;
}

int main (void)
{
time_t start;
pthread_t thread_id;
int num1, num2, ans;

time (&start);

while (time (NULL) - start < MAXTIME) {
srand (start);
num1 = rand () % 100;
num2 = rand () % 100;
ans = num1 + num2;
printf ("please input the answer of %d + %d = ", num1, num2);
fflush (stdout);
if (pthread_create (&thread_id, NULL, (void *)get_answer, NULL))
exit (-1);

while (reading) {
if (time (NULL) - start >= MAXTIME) {
printf ("\nGAME OVER!\n");
return EXIT_SUCCESS;
}
}

if (userans < 0)
return EXIT_SUCCESS;
if (userans != ans) {
printf ("Sorry, Wrong,the correct answer is %d\n", ans);
} else {
printf ("Correct, you are really clever.\n");
}
printf ("Input negative number to terminate\n");
fflush (stdout);
fflush (stdin);
reading = 1;
time (&start);
}
return EXIT_SUCCESS;
}
---8<------8<------8<------8<------8<------8<------8<------8<---

</OT>

Cheers,
 
D

David Thompson

Le Tue, 17 Mar 2009 20:38:04 -0700 (PDT),
SamuelXiao a écrit :
<OT>

Even though you've already get answers, you can try another way of
doing what you are looking for using POSIX threads.
Or any half-decent threads, but POSIX is a fine example.
That said, this is just for the fun. Here is an example, not very
clean, but working enough to show the idea:
Not very clean indeed, in mostly ontopic ways.
---8<------8<------8<------8<------8<------8<------8<------8<---
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <signal.h>

#define MAXTIME 4

int reading = 1;
int userans;

void get_answer (void)
{
int nil;
while (!scanf ("%d", &userans))
while (((nil = getchar ()) != '\n') && nil != EOF);
reading = 0;
}
A pthread threadfunc must take one parameter of type void * (even if
you don't use it for anything) and return void *. Either of these
mismatches officially causes Undefined Behavior in C; in practice, the
wrong (nonstruct) return type often 'happens' to work if not actually
used, but the wrong parameter list frequently does cause problems.
int main (void)
{
time_t start;
pthread_t thread_id;
int num1, num2, ans;

time (&start);

while (time (NULL) - start < MAXTIME) {
srand (start);
num1 = rand () % 100;
num2 = rand () % 100;
ans = num1 + num2;

srand() of the current time is easily predictable and substantially
controllable by a 'player'. If anything important depended on this,
like real gambling, it would be grossly inadequate. But it appears
this is only intended as a learning exercise. Standard C allows time_t
to have forms that would not give useful entropy to srand(); POSIX
does require integer seconds since epoch, although it can easily be
wider than int and C doesn't guarantee signed narrowing is safe.
printf ("please input the answer of %d + %d = ", num1, num2);
fflush (stdout);
if (pthread_create (&thread_id, NULL, (void *)get_answer, NULL))
exit (-1);
If you hadn't put that incorrect(!) cast, your compiler (assuming it's
conforming) is required to detect the type mismatch on the threadfunc
noted above and give a 'diagnostic', in practice probably a warning.
Don't use casts to suppress correct diagnostics and write broken code.
Try your best not to use casts at all.

Exit status < 0 is unuseful in POSIX. Any exit status other than 0 or
EXIT_{SUCCESS,FAILURE} is not fully portable standard C.
while (reading) {
if (time (NULL) - start >= MAXTIME) {
printf ("\nGAME OVER!\n");
return EXIT_SUCCESS;
}
}

POSIX threads, and I believe many others, do NOT guarantee 'fair'
scheduling. It is entirely possible and even likely that this hard
loop will 'hog' the CPU, and the thread that you intended to handle
the input will never run even though there is input available. The
correct way to synchronize between threads is with synchronization
primitives; in this case, a timed_condwait on a condition variable
which get_answer (in the reader thread) signals.

Also, pthreads doesn't guarantee that writes by one thread are visible
(read) by another thread at all without such synchronization, although
in practice they usually are 'reasonably' soon for somewhat variable
values of 'reasonable'; and it also doesn't guarantee that writes are
seen _in order_ without synchronization, and sometimes they aren't,
which would cause this naive code to screw up badly.

Go to comp.programming.threads for (much!) more detailed discussions
of these issues, especially in POSIX. (Despite the generic name, most
of the discussion there is about pthreads specifically.)

The OP didn't say, but I probably wouldn't make timeout 'success'.
if (userans < 0)
return EXIT_SUCCESS;
if (userans != ans) {
printf ("Sorry, Wrong,the correct answer is %d\n", ans);
} else {
printf ("Correct, you are really clever.\n");
}
printf ("Input negative number to terminate\n");
fflush (stdout);
fflush (stdin);

fflush on an input stream is Undefined Behavior in standard C, and on
some (many?) systems doesn't do what you want here; and isn't needed
anyway since you already have code above to discard bad input.
reading = 1;
time (&start);
}
return EXIT_SUCCESS;
}
---8<------8<------8<------8<------8<------8<------8<------8<---

</OT>

Another POSIX-specific (thus equally offtopic) approach is to use
nonblocking I/O and select() or poll() etc. etc. That would be ontopic
(but I bet a FAQ) in comp.unix.programmer .
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top