Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 27

Discussione: [c++] race-condition

  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577

    [c++] race-condition

    ciao,
    mi stavo chiedendo a quali tipi di problemi potrebbe andare incontro un programma server che implementa un thread nel momento in cui deve inviare dati ad uno o più client.

    Non ho molta esperienza in questo genere di programmazione multithread però, dato il seguente scenatio:

    - il processo padre esegue un thread che continua all'infinito a creare dati
    - il thread richiama una funzione SendData() la quale contiene un ciclo for() che consente di inviare i dati agli n client connessi
    - il thread incrementa anche della Label poste sul form del processo padre

    mi chiedo, se il thread in esecuzione è sempre e solo uno, a quali tipi di race condition potrebbe andare incontro un programma server del genere?

    la SendData() in codice Borland Builder è così fatta

    codice:
    void SendData(AnsiString msg)
    {
            try{
                    for(int actconn = 0; actconn < Form1->ServerSocket1->Socket->ActiveConnections; actconn++)
                            Form1->ServerSocket1->Socket->Connections[actconn]->SendText(msg);
    
            } catch(...) { }
    }

  2. #2
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577
    .
    Quote Originariamente inviata da linoma Visualizza il messaggio
    Molte interfacce grafiche consentono all'accesso ai vari controlli solo dal thread principale. Questo se non si controlla crea diversi problemi. Se i threads nn usano le stesse risorse nn hai nessun obbligho di sincronizzazione se non nell'ultima fase, cioe la fine. Diversi sono gli approcci che i vasri so offrono tra cui i mutexes
    ciao,
    usando Borland Builder ad esempio, se in un thread separato accedi ad un componente della sua interfaccia ad esempio, una Label posta sul form principale è il caos e questo accade sia se usi le API di Windows che la classe TThread di Borland stessa: e meno male che nella documentazione si dice che la classe TThread è "thread safe". A questo punto non si capisce cosa vogliono dire quelli di Borlan. Io avevo interpretato che la eventuale sincronizzazione tra il thread scritto dall'utente e quello principale fosse gratis, invece non è così.
    Ultima modifica di misterx; 02-04-2015 a 20:11

  3. #3
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Molte interfacce grafiche consentono all'accesso ai vari controlli solo dal thread principale. Questo se non si controlla crea diversi problemi. Se i threads nn usano le stesse risorse nn hai nessun obbligho di sincronizzazione se non nell'ultima fase, cioe la fine. Diversi sono gli approcci che i vasri so offrono tra cui i mutexes
    Ultima modifica di linoma; 02-04-2015 a 19:42
    Per gli Spartani e Sparta usa spartan Il mio github

  4. #4
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577
    .
    Quote Originariamente inviata da linoma Visualizza il messaggio
    Molte interfacce grafiche consentono all'accesso ai vari controlli solo dal thread principale. Questo se non si controlla crea diversi problemi. Se i threads nn usano le stesse risorse nn hai nessun obbligho di sincronizzazione se non nell'ultima fase, cioe la fine. Diversi sono gli approcci che i vasri so offrono tra cui i mutexes
    ciao,
    usando Borland Builder ad esempio, se in un thread separato accedi ad un componente della sua interfaccia ad esempio, una Label posta sul form principale è il caos e questo accade sia se usi le API di Windows che la classe TThread di Borland stessa: e meno male che nella documentazione si dice che la classe TThread è "thread safe". A questo punto non si capisce cosa vogliono dire quelli di Borlan. Io avevo interpretato che la eventuale sincronizzazione tra il thread scritto dall'utente e quello principale fosse gratis, invece non è così.
    Ultima modifica di misterx; 02-04-2015 a 20:12

  5. #5
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Ripeto è un problema comune a molte UI da Windows a Linux, il discorso che è alla base è una corretta condivisione delle risorse. Tempo fa succedeva anche cn .NET, oggi credo sia la stessa cosa. Per una buon multithreads cn un uso dei vari cores bisogna orginazzare il codice in maniera ottimale dividendo l'elaborazione dalla grafica.
    Per gli Spartani e Sparta usa spartan Il mio github

  6. #6
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577
    Quote Originariamente inviata da linoma Visualizza il messaggio
    Ripeto è un problema comune a molte UI da Windows a Linux, il discorso che è alla base è una corretta condivisione delle risorse. Tempo fa succedeva anche cn .NET, oggi credo sia la stessa cosa. Per una buon multithreads cn un uso dei vari cores bisogna orginazzare il codice in maniera ottimale dividendo l'elaborazione dalla grafica.
    buono a sapersi, grazie 1000

    p.s.
    mi chiedo ancora in cosa competono due thread, quello principale ed uno secondario che scrive una Label. Fosse uno spostamento di un indirizzo posso capire ma una Label non mi è chiaro

  7. #7
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Intanto cambiare testo ad una label implica non solo un diverso contenuto della memoria, se nn proprio zona della memoria diversa, ma implica un ridisegno del video che è vincolato alla frequenza di refresh e per evitare sfarfalii va fatto al momento giusto e col modo giusto quindi strettamente vincolato all'elettronica del device. A dire il vero se nn vedo il codice delle varie UI posso solo ipotizzare il motivo per cui il limite del thread principale e mi viene in mente solo quello descritto che in un SO complesso non è poco
    Per gli Spartani e Sparta usa spartan Il mio github

  8. #8
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    577
    errori a parte il codice è come questo. Ora stavo provando ad usare i comandi per le sezioni cridiche ma credo di avere una enorme lacuna; osservando il codice io scrivo:


    InizioSezioneCritica()
    Form1->Caption->Label1 = i;
    FineSezioneCritica()

    ho usato due comandi inventati; ma si direbbe che non devo proteggere i metodi, come invece ho scritto, ma solo le eventuali variabili globali condivise.


    codice:
    //---------------------------------------------------------------------------
    #include <vcl\vcl.h>
    
    #pragma hdrstop
    
    #include "Unit1.h"
    
    HANDLE MyThread;
    DWORD WINAPI ThreadTest( LPVOID lpParameter );
    DWORD ID1;
    
    //---------------------------------------------------------------------------
    
    #pragma link "Grids"
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
    {
     }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
            MyThread=CreateThread(NULL,0,ThreadTest,NULL,0,&ID1);
            Form1->Caption = "Started.....";
    }
    //---------------------------------------------------------------------------
    
    DWORD WINAPI ThreadTest( LPVOID lpParameter )
    {
       for(int i=0; i<10000; i++)
                      Form1->Label1->Caption=i;
    
            Form1->Caption = "Stopped.....";
            Sleep(50);
    }
    //---------------------------------------------------------------------------

  9. #9
    Nei sistemi operativi mainstream il refresh video e l'hardware non c'entrano niente, è tutta roba che viene gestita in kernel mode a valle del rendering dei pixel che fanno le applicazioni/i toolkit, e che gira sostanzialmente per i fatti suoi. I problemi sono sostanzialmente i soliti problemi di multithreading che si hanno in qualunque applicazione che manipola degli oggetti che hanno uno stato non banale, ovvero che praticamente qualunque operazione che ci vai a fare su non è atomica, e se più thread fanno la stessa operazione contemporaneamente fai su casini apocalittici nelle strutture interne. Anche solo impostare il testo di una label è un pasticcio: mentre un thread disegna il testo l'altro glielo cambia dietro la schiena (tra l'altro non in maniera atomica, per cui si passa ad esempio per stati in cui la lunghezza è sbagliata o indefinita), modificandone la lunghezza, con in risultato output assurdi.

    Tra l'altro, la maggior parte dei toolkit di GUI hanno anche dello stato globale condiviso tra tutti i widget/finestre, anche quello andrebbe sincronizzato.

    Le API Win32 risolvono il problema dando un'affinità per thread ad ogni finestra, e facendo sì che la comunicazione con le finestre passi sempre tramite message queues: la SendMessage chiama direttamente la window procedure se siamo nel "suo" thread, altrimenti accoda il messaggio e aspetta che l'altro thread l'abbia processato e fornito una risposta.
    Dato che comunque anche solo ragionare su una GUI a cui accedono più thread è complicato e il "trucco" di rientrare dal message loop del thread GUI è sempre possibile, la maggior parte dei toolkit GUI ignorano il problema: le chiamate "normali" si assumono fatte dal thread GUI, nei rari casi in cui serve fare modifiche alla GUI da un altro thread si accoda un evento alla message queue e lo si gestisce nel thread principale.
    Quote Originariamente inviata da misterx
    mi chiedo ancora in cosa competono due thread, quello principale ed uno secondario che scrive una Label. Fosse uno spostamento di un indirizzo posso capire ma una Label non mi è chiaro
    In generale, la domanda che ci si pone normalmente è esattamente l'opposto: se hai degli oggetti condivisi "in scrittura" tra più thread, fino a prova contraria sei sicuro che hai delle race condition.
    e meno male che nella documentazione si dice che la classe TThread è "thread safe". A questo punto non si capisce cosa vogliono dire quelli di Borlan. Io avevo interpretato che la eventuale sincronizzazione tra il thread scritto dall'utente e quello principale fosse gratis, invece non è così.
    La classe TThread non è magica... per avere codice thread safe anche l'oggetto a cui si accede deve essere della partita - ovvero, deve avere un qualche genere di mutex che protegga l'accesso ai dati di classe. Quello che intende la documentazione è che gli oggetti di tipo TThread sono thread-safe, ovvero puoi accedere a qualunque membro di un'istanza di TThread da qualunque thread.
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    Quote Originariamente inviata da misterx Visualizza il messaggio
    errori a parte il codice è come questo. Ora stavo provando ad usare i comandi per le sezioni cridiche ma credo di avere una enorme lacuna; osservando il codice io scrivo:
    Lascia stare le critical section, l'unico modo sensato di lavorare su GUI pensate per il single threading da altri thread è serializzare l'accesso ripassando per l'event loop, praticamente tutti i toolkit grafici hanno un qualche sistema per consentirti di eseguire codice nel thread GUI facendo questo giro (Control.Invoke in .NET, le queued connection in Qt, SendMessage più un messaggio "speciale" in Win32, ...).
    ---edit---
    Appunto, c'è TThread.Synchronize.
    Ultima modifica di MItaly; 02-04-2015 a 22:33
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.