Newsgroup: it.comp.lang.c++
Titolo: Intercettare pressione tasto ESC

Sto' scrivendo un Application Console, devo fare si d'interrompere un ciclo
while alla pressione del tasto esc senza interrompere l'esecuzione del
programma.
In pratica continuo a ciclare, quando premo esc m'interrompo.
Che comando/API posso utilizzare?


Niente che abbia a che fare con Standard C++.
Devi usare il multiprocess (fork()) e i segnali perché mentre un primo
processo esegue il while l'altro è in attesa di qualcosa dallo standard
input. Quando quest'ultimo processo riceve un carattere specifico da
tastiera, o da dove vuoi tu, invia un segnale all'altro processo che se
gestito correttamente da un handle, interrompe il while.
Buon divertimento,
FabioMDF
 
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 Che comando/API posso utilizzare?
Forse c'e' pure una API (in ogni caso siamo OT),
cmq prova questo:
while (ch != 0x1b)
Ciao
-- 
-> Linux Registered User #365929
-> GnuPG KeyID: 0x048EFB85
-> 
http://www.cikko.tk

> ch;". A quel punto come farebbe la while ad operare senza che qualcuno
almeno prema invio ad ogni ripetizione?
Ciao,


 almeno prema invio ad ogni ripetizione?
Infatti...la mia soluzione temporanea sarebbe ad es.:
while(kbhit()!=1)
        printf("a");
anche se kbhit non mi sembra molto elegante.
La fork() sotto windows non esiste o sbaglio? Sempre usata sotto linux/unix.
Bye
Gio

 
Hai ragione fabiomdf,
ho dato una risposta a meta': immagino che se devi intercettare un tasto da 
tastiera,
immagino pure che stai leggendo qualcosa in input da tastiera.


 Gio
Ciao,
fabiomdf


Invece devo ciclare infinitamente finche' non premo il tasto ESC...kbhit() č
stata introdotta dalla borland e fa' parte della conio.h, torna un valore
differente da 0 se č stato premuto un tasto qualsiasi.
Usando il cin, getch e simili interrompo il ciclo, finche' l'utente non
schiaccia un tasto.
Io devo continuamente inviare un valore sulla rs232 e riceverne uno
visualizzandolo, quando premo esc interrompo il tutto.

 gestito correttamente da un handle, interrompe il while.
Uh?! Perche' farla cosi' complicata? Gia' che suggerisci fork che non e'
standard potevi anche suggerire qualche cosa di piu' pratico, ovvero una
funzione gia' fatta non blocking...
Tommy

 essere almeno una API simile a fork().
No, la fork in quanto tale non esiste. Ad ogni modo esiste createprocess,
createthread etc... Windows e' molto ricco in materia di
multithreading/multitasking/multiprocessing. Ad ogni modo la fork andrebbe
usata con cautela, fork crea due processi identici, quindi raddoppia la
quantita' di memoria in uso etc... Creare invece un semplice thread che
esegua solo il task richiesto (che gira sotto lo stesso processo) e che usa
solo il suo thread local storage e' una soluzione molto piu' rapida e piu'
leggera. Anche il context switching risulta piu' veloce. La programmazione
sotto linux ha per troppo tempo abusato della fork.
Ad ogni modo siamo OT.
Tommy

 Tommy
Ciao,
Credo che tu non conosca bene l'implementazione dei threads in Linux. Anche
se siamo OT come hai ricordato è bene che si chiarisca come funzionano i
threads in Linux perché molta gente anche qui li usa nei propri programmi
C++. E non fa male sapere che succede ai nostri programmi quando vanno in
esecuzione, anche perchè potrebbe migliorare il modo di progettarli e
realizzarli. Anche per questo io penso che tutti i programmatori dovrebbero
imparare un Assembly almeno e gli internals di un OS.
Se dovessero essere necessarie altre precisazioni trasferiamo il discorso su
it.comp.os.linux.development.
Comunque chi non è interessato è stato avvertito dell' OT (quasi in
tempo...)
Linux non fa NESSUNA differenziazione tra processi e threads. Non li
distingue proprio. Ogni thread come ogni processo ha una sua struct task_t
(definita in tuo_src_linux/include/linux/sched.h) che lo differenzia dagli
altri. Infatti ogni task_t di ogni singolo processo/thread (d'ora in poi
quando scrivo solo processo intendo che il discorso vale anche per i
threads) non viene individuato dal pid ma da un puntatore ad una struct
task_t contenuto all'interno di una struct thread_info allocata nel process
kernel stack. Threads/Processi sono inseriti in una circular doubly-linked
list (una per ogni livello di priorità) run_queue per processore e sono
schedulati indipendentemente: quindi se hai tre pid in esecuzione di cui uno
con due threads hai esattamente quattro processi con quattro task_t in lista
da schedulare.
Il context-switching sia di processi che di threads (ma è inutile continuare
a chiamarli diversamente) è effettuato dallo stesso codice e nell'ordine
prima kernel/sched.c/context_switch() poi
include/asm/mmu_context/switch_mm() e infine
include/asm/system.h/switch_to(). Nessuna differenza, mi ripeto.
Sia fork() che pthread_create() finiscono per essere implementate
internamente con clone() però con alcuni parametri differenti che
stabiliscono solo quali risorse condividere nel caso di threads, fork() e
vfork(): questi parametri stabiliscono quali sono le risorse in temini di
address space, filesystem resources, file descriptors e signal handlers
trasferire al processo creato inizialmente con pthread_create e NON al
processo creato inizialmente con vfork() e fork(). In ogni caso Linux
implementa un meccanismo di copy_on_write che annulla anche la necessità di
copiare in un altro spazio le risorse da non condividere fino a che non si
deve scrivere su di esse.
Ci sono motivi ben validi per scegliere di utilizzare fork() oppure
pthread_create() e risiedono SOLO nella necessità o meno di condividere le
risorse specificate nel precedente paragrafo.
 Per quanto riguarda il mio consiglio di usare fork() nel risolvere il
problema con i segnali si deve considerare che i threads condividono i
signal handlers per via della chiamata a clone con i parametri che ti
elencavo prima. Quindi non puoi inviare un segnale ad un solo thread perchè
tutti i threads andrebbero ad eseguire lo stesso handler. E nel mio esempio
si proponeva che un processo fosse biforcato con fork() in modo che il padre
continuasse poi con l'esecuzuione del while da interrompersi con un segnale
inviato dal figlio che rimane in ascolto per il giusto carattere dallo input
stream (std::cin).
 
Saluti


 internamente con clone() ...
Una implementazione simile di pthreads esiste ed e' estremamente comune, ma
non ha molto senso, si chiama LinuxThreads. (e qui si potrebbero sentire
alcuni appassionati che si ribellano).
Tommy


Mi scuso ancora se ti sono sembrato offensivo nel dire che forse non conosci
come è implementato il Linux kernel, si tratta solo del fatto che se non
lavori sul codice dello stesso molte cose possono sfuggire.
Buon lavoro e saluti,


 lavori sul codice dello stesso molte cose possono sfuggire.
E' vero, non sono uno studioso del kernel di linux, il mio discorso era un
pochino piu' ad alto livello e comunque su cose che, nonostante la mia
parziale ignoranza in materia, conosco perche' sono cose semplici che si
sanno. Credo solo che si siamo fraintesi e cmq non credo affatto tu sia
stato offensivo.
Io lavoro in ambienete windows ed su sistemi embedded con microkernels ( che
comunque supportano processi ). Presto passeremo ad O.Ss. basati su linux,
chissa' che non diventi un esperto di linux! Un progetto in ditta c'e' gia'
solo che io al momento sto lavorando su altri due progetti (sto lavorando ad
un case-tool fatto in C++, per windows, per generare applicazioni e menu per
set-top-boxes in stile visual basic; un visual basic (che usa il C) per i
ricevitori di digitale terrestre! Oltre a questo sto lavorando allo sviluppo
di una nuova implementazione per OAD (over the air download)). Come vedi non
mi occupo dello sviluppo di sistemi operativi, il mio esame di sistemi
operativi l'ho dato ;-)
Tommy