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 .