Newsgroup: it.comp.lang.c
Titolo: Gestione eventi in parallelo(?)

Premetto che sono alle prime armi con la programmazione in C.
Come posso implementare un programma che mi permetta di acquisire da
tastiera un valore e contemporaneamente tenere memoria di un countdown che
vada da n a 0:
esempio.
Voglio acquisire un valore con scanf entro 10 secondi, al termine dei quali
il programma termina o passa ad un altra istruzione.(farlo terminare anche
in assenza di input)
Grazie della cortese attenzione e della disponibilita'.
Artan

La prima cosa che mi viene in mente (non è detto che sia la più 
semplice) è quella di fare una fork() e generare un processo figlio..
a questo punto il figlio fa il conteggio del tempo e quando scade invia 
un signal (dopodichè muore) al padre che poi deciderà il da farsi..
sotto che OS devi compilarlo?
ciao
jac



Devo compilarlo sotto windows. Non avresti un codice che sia piu' esaustivo
in termini di comprensione?Il problema e' che non ho la piu' pallida idea di
cosa sia un processo figlio e di come implementare la funzione fork().
Grazie per la celerita' della risposta.
Artan

Se è per win non ti posso essere d'aiuto, non lo conosco come OS..
fork() è una funzione di sistema (Linux) non è ANSI C.. idem per i 
SIGNAL..(magari esistono i corrispondenti per win, ma nn conosco)
ciao
jac


 ha scritto nel messaggio
news:U93Ca.3528$Fr5....@tornado.fastwebnet.it...

Magari dico una cavolata, ma non si può usare la programmazione multithread
in c?

 in c?
oh raga' .. ma stiamo scherzando?!? multithread per aspettare la pressione
di un tasto?
e' un modo facile per incasinarsi la vita =)
visto che si e' sotto windows si usa un interrupt del dos e ce la caviamo
ocn molto meno lavoro.
INT 21 - DOS 1+ - GET STDIN STATUS
 AH = 0Bh
Return :
      AL = status
     00h if no character available
     FFh if character is available
Quindi diciamo che una cosetta scritta cosi al volo sarebbe:
INIZIO:
{qui qualcosa tipo if  tempo==(tempo_iniziale)+pausa vai a FINE}
MOV AH,0Bh    ;0Bh controlla il buffer
INT 21h              ;chiama l'interrupt
CMP AL,FFh      ;compara AL e FFh
JNE INIZIO        ;se non sono uguali vai a INIZIO
MOV AH,01h     ;01h - leggi carattere con echo
INT 21h              ;chiama l'interrupt
FINE:
ps = spero di non aver fatto cappelle perche' l'ho scritto un po' al volo
--
Keita'
--
ATI drivers on Linux, firmate la petizione!
http://www.petitiononline.com/xf123456/petition-sign.html
?

 SIGNAL..(magari esistono i corrispondenti per win, ma nn conosco)
e da man 2 signal 
CONFORMING TO
       ANSI C

 FINE:
Beh, l'assembly non e' per caso un altro modo per incasinarsi la vita ;-)
?!?
Ricordo anche se e' OT che sotto windows esistono le win32 APIs che si
possono comodamente chiamare da un programma C.
Esistono alcune funzioni non-blocking che dicono che se un tasto e' stato
premuto o meno, come ad esempio: _kbhit()
Tommy

 premuto o meno, come ad esempio: _kbhit()
Beh certo, poi dipende dalla dimestichezza che uno ha con l'una o con
l'altra cosa, per esempio io le API non le ho mai usate (anche perche i
programmi che faccio non ne hanno mai bisogno), mentre l'asm lo uso spesso
(un po' per tutto, spesso sacrificando portabilita').


 ha scritto nel messaggio
news:JskCa.25208$pR3.5...@news1.tin.it...


}
ammazzare una scanf su un altro thread non mi sembra una "buona
pratica da seguire"
su un nix puoi fare qualcosa come:
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int data_available_on_stdin(unsigned int sec)
{
    fd_set theSet;
    struct timeval tv;
    tv.tv_sec  = sec;
    tv.tv_usec = 0;
    FD_ZERO(&theSet);
    FD_SET(0, &theSet);
    select(0+1, &theSet, 0 ,0 , &tv);
    return FD_ISSET(0,&theSet);
}
#include <stdio.h>
int main(int argc, char*argv[])
{
        char buffer[1024];
        printf("Inserisci una stringa (4 secondi):\n");
        if( !data_available_on_stdin(4) )
        {
            printf("Tempo trascorso\n");
            return 1;
        }
        fgets(buffer,sizeof(buffer), stdin);
        printf("La stringa era: %s",buffer);
        return 0;
}
... questo facendo affidamento su un terminale buffered. 
Da windows puoi fare qualcosa di simile con WaitForSingleObject 
su GetStdHandle(STD_INPUT_HANDLE)... giusto più macchinoso perché
l'handle viene segnalato anche per altri eventi, nulla ti vieta di
peekarli e toglierli dal buffer quando ti arrivano però.
sbirish

 questo thread possa venire deschedulato.
Beh, leggi questo pezzo tratto da Richter:
<QUOTE>
A thread can also tell the system that it does not want to be schedulable
for a certain amount of time. This is accomplished by calling Sleep:
VOID Sleep(DWORD dwMilliseconds);
This function causes the thread to suspend itself until dwMilliseconds have
elapsed.
...
Calling Sleep allows the thread to voluntarily give up the remainder of its
time slice.
</QUOTE>
Ovviamente essendo windows un sistema operativo non real-time dwMilliseconds
non e' un valore reale ma approssimativo.
Cmq tutta questa discussione e' OT.
Tommy

 manca una CloseHandle() tra l'altro
Perfettamente d'accordo, è il famoso kill. E dichiarato. Su sistemi NT (gli
unici Win* degni di chiamarsi sistemi operativi) comunque se la cava...
Siamo quasi al limite dell'OT...
Ciao,
Paolo

non e' un valore reale ma approssimativo.
il fatto è che si, può essere deschedulato (forse, non te lo
garantisce nessuno), ma continua comunque a pollare.
provalo... fai prima e vedi che di cpu ne mangia cmq
sbirish

Beh, leggi questo pezzo tratto da Richter:
#include <windows.h>
int main(){ for(;;)::Sleep(0); }
questo da me fa un 98% di cpu...
sbirish

 sbirish
Sbirish, compila questo codice:
#include <windows.h>
int main()
{
  while (1)
    Sleep(1);
}
Adesso sě che siamo OT. Basta dirlo :)
Ciao,
Paolo.

 int main(){ for(;;)::Sleep(0); }
che esempio cretino!!!
sleep 0 non dorme affatto(**) e tu lo metti in un ciclo stretto.
e' come dire:
lavora_come uno_scemo_senza_dormire(), ovvio che ti consuma il 100% !!! (a
me infatti consuma il 100%).
scrivere Sleep(0) e' come non scriverlo (**).
prova con:
#include <windows.h>
int main(){
    for(;;){
        ::Sleep(100);
    }
}
ora vedrai che Sleep fara' dormire per 100 millisecondi (un decimo di
secondo) poi di nuovo e poi di nuovo.
Guarda la percentuale della CPU e' vedrai che e' sotto il 3%
(probabilmente). (a me rimane 1%).
Cosa volevi dimostrare con Sleep(0) ?!?
** sleep(0) fa solo smettere il rimanente dello slice attuale ma non fa per
nulla "dormire" il thread.
Mi accorgo ora che il post originale aveva uno Sleep(1) che non ha molto
senso per lo stesso motivo. Ad ogni modo provalo, questo dovrebbe comunque
tenerti la CPU abbastanza bassa (a me sta al 3%). Poi ovvio quando si usa
Sleep, dai 20ms in poi si hanno grossi benefici, non essendo windows un
sistema real-time.
Tommy

Tommy
sbirish

}
solito.. 97-98% di cpu

essere uguale.
ehrm 1 viene approssimato =)
sbirish

solito.. 97-98% di cpu
mh.. se abbasso la priorità però scende allo 0-1%
sbirish.

 essere uguale.
Non sono d'accordo.
Sleep(0) passa l'esecuzione ad un altro trhead, ma non lo fa dormire, la
volta dopo ci rientra subito. guarda la documentazione.
windows non e' un os real-time.
Tommy