Newsgroup: it.comp.lang.c++
Titolo: Niubbo e ciclo while

Salve ragazzi,
sto muovendo i miei primi passi in C++ e mi sto scontrando con un
problemino, ovvero come posso in un cliclo while dare spazio anche agli
eventi generato da altri oggetti?
Mi spiego meglio, ho un ciclo di attesa fatto cosě (non mangiatemi per
questo):
while (!Flag) {}
dove Flag č una variabile di tipo booleana che viene settata in un oggetto
NMUDP (Borland C++ Builder 6) all'arrivo di un determinato pacchetto.
Peccato che il ciclo cosě fatto č letteralmente un loop che pianta il
programma, mi dareste qualche indicazione di come ovviare a questo problema?
Grazie in anticipo


Potresti mettere il tuo programma dentro un ciclo infinito e controllare 
ad ogni passaggio se Flag == true. Naturalmente devi riorganizzare la 
logica per gestire gli eventi, considerando come evento anche il normale 
funzionamento del programma. Tanto per capirci un sistema simile alla 
gestione eventi di Windows.
Imho, č molto piů agevole creare un nuovo thread e lasciarlo in attesa 
dell'evento mentre nel programma principale fai altro.

Grazie ad entrambi per l'interssamento, credo che mi orienterň sul
multithreading anche se al momento non ho la piů pallida idea di come
procedere.
Buona serata a tutti
P.S. -- Scusate il ritardo nel rispondere ma sono stato fuori casa tutto il
giorno.

 o eventualmente a creare un Timer esterno che interrompa il
già provato senza successo,

 dell'evento mentre nel programma principale fai altro.
non credo sia fattibile la prima ipotesi, vedrò di orientarmi sul secondo
metodo

 
Il C++ non incorpora alcuna nozione di "evento".
Se vuoi scrivere codice portabile dovrai appoggiarti a un framework 
multipiattaforma che supporti il concetto di "evento" che hai in mente.
Max

 multipiattaforma che supporti il concetto di "evento" che hai in mente.
Ho scelto il Borland perchč mette a disposizione le librerie CLX che
dovrebbero permettere di poter ricompilare in maniera quasi indolore lo
stesso programma in ambiente win32 che linux.

 funzione di attesa ?
Il problema è che il classico sleep, in condizioni di singolo thread, ferma
tutto.
L'evento OnTimer e simili non vengono scatenati se il thread è monopolizzato
da un loop tipo il while che speravo di adottare, forse per i motivi che
avete sottolineato relativamente alla natura del linguaggio.
Escluse le vie più classiche e note, la mia limitata conoscenza del C++ non
mi permette di fare di meglio, ecco il motivo del chiedere una indicazione o
uno spunto su cui lavorare. Hai qualche idea?

Iw7 wrote:

beh ... questo però è strano e implica che il componente TIMER 
del Borlanc C++ Builder, forse per motivi di design tesi a 
impoverire meno le risorse globali di sistema (in Windows 98 ad 
es. i Timer erano risorse globali, molto limitate di numero, 
preziose e che appesantivano assai l'intero sistema se 
scatenavano eventi a cadenza fitta), sono stati implementati ad 
un livello ulteriore rispetto ai timer di sistema veri e propri.
I timer di visual basic (l'help consigliava di non avvicinarsi 
mai all'uso di sedici timer tutti attivi contemporaneamente) 
probabilmente erano solo involucri per i timer stessi di 
sistema, i quali non erano influenzati dai loop o applicazioni 
di monopolizzazione della CPU, e scatenavano eventi ugualmente 
(i quali erano gestibili se nel loop veniva messo il DoEvents).
E' possibile, ma sparo solo una ipotesi, che la libreria del 
C++Builder usi magari un unico Timer di sistema vero e proprio 
dietro le quinte, e lo "spartisca" tra eventuali vari oggetti 
Timer esposti all'utente. O addirittura che usi altri meccanismi 
di temporizzazione tutta interna alal libreria ancora più 
leggeri per l'O.S. (ma ovviamente più vulnerabili all'abuso 
della CPU). Ripeto, faccio solo ipotesi,
Cmq citando, Make it work before you make it better (and keep it 
work while you get it better) .... ti consiglio magari tanto per 
provare la logica del programma di cercare una API di un O.S. 
limitato, mascherarla in una funzione di incapsulamento e farlo 
girare così. Se funge, poi intanto cerchi funzioni generiche 
multipiattaforma che facciano il compito di restituire il 
controllo all'O.S. come DoEvents o le API corrispettive.
ciao
Soviet-Mario


 girare cosě.
effettivamente č una toppa che permetterebbe di passare di un sistema
operativo all'altro sostituiendo solo questa funzione.
Ti ringrazio tanto per il tempo dedicatomi.
A presto

Per tutti coloro a cui potrebbe interessare ho trovato una "pezza a colori"
che al momento mi risolve qualche problema.
E' stato sufficiente piazzare il ciclo di attesa in un nuovo thread, e anche
se la cpu schizza al 90 e passa %, il thread principale non perde mai il
controllo della situazione.
Praticamente ho adattato alle mie necessità il codice riportato nell'help
della Borland (cfr _beginthread). Da quello che ho capito è una soluzione
alquanto portabile tra i diversi S.O..
Riporto il codice che ho usato per una prima prova.
//--------------------------------------------------------------------------
-
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include <stddef.h>     /* _threadid variable */
#include <process.h>    /* _beginthread, _endthread */
#include <errno.h>
//--------------------------------------------------------------------------
-
#pragma package(smart_init)
#pragma resource "*.dfm"
bool Flag;
TForm1 *Form1;
//--------------------------------------------------------------------------
-
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
}
//--------------------------------------------------------------------------
-
void thread_code(void *threadno)
{
    while (Flag){}
    Form1->Label1->Caption="Thread terminated.";
   _endthread();
}
//--------------------------------------------------------------------------
-
void start_thread(int i)
{
    int thread_id;
#if     defined(__WIN32__)
    if ((thread_id = _beginthread(thread_code,4096,(void *)i)) == (unsigned
long)-1)
#else
    if ((thread_id = _beginthread(thread_code,4096,(void *)i)) == -1)
#endif
    {
        Form1->Label1->Caption="Unable to create thread.";
        return;
    }
    Form1->Label1->Caption="Thread created.";
}
//--------------------------------------------------------------------------
-
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Button1->Enabled=false;
   Flag=true;
   Timer1->Enabled=true;
   start_thread(1);
}
//--------------------------------------------------------------------------
-
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
   Timer1->Enabled=false;
   Button1->Enabled=true;
   Button1->SetFocus();
   Label1->Caption="";
   Flag=false;
}
//--------------------------------------------------------------------------
-


non c'entra nulla col C++ ma metti uno Sleep() se non vuoi occupare 
inutilmente la CPU.
    while (Flag) { Sleep(100); }

 ha scritto nel messaggio
news:a6UOe.96995$fm.65...@news4.tin.it...

come già detto nei post precedenti, lo sleep() non fa al caso mio,
soprattutto perchè l'eventuale occupazione della CPU ha una durata di
qualche frazione di secondo, giusto il tempo massimo concesso
all'apparecchio con cui devo comunicare di rispondermi.