* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Novembre 01, 2024, 01:07:09 am

Inserisci il nome utente, la password e la durata della sessione.

104 Visitatori, 0 Utenti

Autore Topic: Passare dati a un nuovo thread  (Letto 9114 volte)

Diego1981

  • Full Member
  • ***
  • Post: 180
  • Karma: +0/-0
Passare dati a un nuovo thread
« il: Febbraio 13, 2017, 08:36:02 am »
Ciao Ragazzi
avevo una curiosità che non trova risposta  ;D
Creo un nuovo thread, nel costruttore assegno una classe da passare al thread
Come mai la classe nel thread(osservando il debug) perde tutti i dati quando la classe nel tread principale viene eliminata? (almeno penso)
Sto lavorando con il componente http server indy

aggiungo giusto 2 righe di codice
nella form principale
procedure TFR_Principale.HTTPServerCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
SesThrd:=Tusessionthrd.Create(False,ARequestInfo,AResponseInfo,AContext);
end;

nel thread
constructor Tusessionthrd.Create(CreateSuspended: Boolean;
  RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo;
  Acontext: TIdContext);
begin
  inherited Create(CreateSuspended);
  ARequestInfo:=TIdHTTPRequestInfo.Create;
  ARequestInfo:=RequestInfo;//provo in questo modo
// ARequestInfo.Assign(RequestInfo);//ho provato anche cosi
.....
....
end;

Quando il Thread passa alla procedura execute nel debug la mia classe Arequestinfo perde tutti i dati, si svuota
Cosa mi perdo????
grazie a tutti

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2917
  • Karma: +20/-4
Re:Passare dati a un nuovo thread
« Risposta #1 il: Febbraio 13, 2017, 09:34:30 am »
probabilmente (qua mi gioco la reputazione :D) l'oggetto ARequestInfo viene distrutto dal thread principale al rientro da Tusessionthrd.Create
quindi il puntatore nel nuovo thread punta ad un oggetto che è stato distrutto

potresti provare:
1) in TFR_Principale.HTTPServerCommandGet, clona ARequestInfo (ad esempio in ThreadSafeARequestInfo)
2) crea il thread con:
Codice: [Seleziona]
SesThrd:=Tusessionthrd.Create(False,ThreadSafeARequestInfo,AResponseInfo,AContext);
3) assicurati che il thread distrugga ThreadSafeARequestInfo quando ha terminato il lavoro

speriamo bene :)
facci sapere
« Ultima modifica: Febbraio 13, 2017, 09:37:30 am da nomorelogic »
Imagination is more important than knowledge (A.Einstein)

Diego1981

  • Full Member
  • ***
  • Post: 180
  • Karma: +0/-0
Re:Passare dati a un nuovo thread
« Risposta #2 il: Febbraio 13, 2017, 10:15:06 am »
grazie nomore
ora provo ma il dubbio è
se Arequestinfo lo dichiaro nella parte private del mio thread

Tusessionthrd=class(TThread)
    procedure LoginPage;
    ....
    ....
  private
    ARequestInfo:TIdHTTPRequestInfo;
    AResponseInfo:TIdHTTPResponseInfo;
    ....
    ....

come può distruggerlo il thread principale? Non dovrebbe passare ad ARequestinfo le informazioni che vengono allocate in un'altra parte di memoria che ovviamente non corrisponde a quella di RequestInfo (scusa la similitudine dei nomi)
grazie
« Ultima modifica: Febbraio 13, 2017, 10:21:18 am da Diego1981 »

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2917
  • Karma: +20/-4
Re:Passare dati a un nuovo thread
« Risposta #3 il: Febbraio 13, 2017, 10:38:59 am »
forse non ho capito bene,
se ARequestInfo lo dichiari in private della classe del thread come fa il thread principale ad accedere al valore? Forse ci sono più dichiarazioni con lo stesso nome, una interna al thread principale ed un'altra nel child thread?

Detto questo può anche essere il thread che, nella sua create (e quindi prima di tornare nel main thread), si fa un clone e se lo conserva per il suo utilizzo (per poi distruggerlo al termine).

Consiglio: Il puntatore nel thread lo chiamerei ThreadRequestInfo.
Imagination is more important than knowledge (A.Einstein)

Diego1981

  • Full Member
  • ***
  • Post: 180
  • Karma: +0/-0
Re:Passare dati a un nuovo thread
« Risposta #4 il: Febbraio 13, 2017, 10:52:48 am »
riprovo avendo moficiato i nomi, spero crei meno confusione

form principale

procedure TFR_Principale.HTTPServerCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
SesThrd:=Tusessionthrd.Create(False,ARequestInfo,AResponseInfo,AContext);
end;

thread Tusessionthrd

Tusessionthrd=class(TThread)
    procedure ....
    ....
    ....
  private
    ThrdARequestInfo:TIdHTTPRequestInfo;
    ....
    ....
  public
    constructor Create(CreateSuspended:Boolean;
ARequestInfo:TIdHTTPRequestInfo;AResponseInfo:TIdHTTPResponseInfo;
      Acontext:TIdContext);

protected
    procedure Execute; override;

  end;
 

constructor Tusessionthrd.Create(CreateSuspended: Boolean;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
  Acontext: TIdContext);
begin NEL COSTRUTTORE PASSO LA CLASSE "AREQUESTINFO" CHE ARRIVA DALLA FORM PRINCIPALE ALLA CLASSE PRIVATA "THRDAREQUESTINFO" DEL THREAD
  inherited Create(CreateSuspended);
  ThrdARequestInfo:=TIdHTTPRequestInfo.Create;
  ThrdARequestInfo:=ARequestInfo; NON E' QUI CHE VIENE ALLOCATA IN UNA NUOVA PARTE DI MEMORIA LA NUOVA CLASSE ?????O MEGLIO...LA CLASSE COPIATA
....
....
....


vedi se è più chiaro
grazie

« Ultima modifica: Febbraio 13, 2017, 11:01:43 am da Diego1981 »

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2917
  • Karma: +20/-4
Re:Passare dati a un nuovo thread
« Risposta #5 il: Febbraio 13, 2017, 11:28:04 am »
constructor Tusessionthrd.Create(CreateSuspended: Boolean;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
  Acontext: TIdContext);
begin NEL COSTRUTTORE PASSO LA CLASSE "AREQUESTINFO" CHE ARRIVA DALLA FORM PRINCIPALE ALLA CLASSE PRIVATA "THRDAREQUESTINFO" DEL THREAD
  inherited Create(CreateSuspended);
  ThrdARequestInfo:=TIdHTTPRequestInfo.Create;
  ThrdARequestInfo:=ARequestInfo; NON E' QUI CHE VIENE ALLOCATA IN UNA NUOVA PARTE DI MEMORIA LA NUOVA CLASSE ?????O MEGLIO...LA CLASSE COPIATA

Prova così

Codice: [Seleziona]
constructor Tusessionthrd.Create(CreateSuspended: Boolean;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
  Acontext: TIdContext);
begin // NEL COSTRUTTORE PASSO LA CLASSE "AREQUESTINFO" CHE ARRIVA DALLA FORM PRINCIPALE
  inherited Create(CreateSuspended);
  ThrdARequestInfo:=TIdHTTPRequestInfo.Create;  // crea nuova istanza e valorizza puntatore
  ThrdARequestInfo.Assign(ARequestInfo); // copia i valori nell'istanza ThrdARequestInfo leggendo da istanza ARequestInfo
  ...

quando mandi in esecuzione vedi se ARequestInfo è valorizzato e se si valorizza ThrdRequestInfo
« Ultima modifica: Febbraio 13, 2017, 11:31:26 am da nomorelogic »
Imagination is more important than knowledge (A.Einstein)

Diego1981

  • Full Member
  • ***
  • Post: 180
  • Karma: +0/-0
Re:Passare dati a un nuovo thread
« Risposta #6 il: Febbraio 13, 2017, 01:06:20 pm »
Avevo già provato anche questa forma ma ThrdArequestInfo non si valorizza
 :o

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2917
  • Karma: +20/-4
Re:Passare dati a un nuovo thread
« Risposta #7 il: Febbraio 13, 2017, 03:17:49 pm »
ARequestInfo è valorizzato?
Imagination is more important than knowledge (A.Einstein)

xinyiman

  • Administrator
  • Hero Member
  • *****
  • Post: 3270
  • Karma: +12/-0
Re:Passare dati a un nuovo thread
« Risposta #8 il: Febbraio 13, 2017, 03:25:01 pm »
Fai prima a mettere un esempio che replica il problema...così ti possiamo aiutare senza andare alla cieca
Ieri è passato, domani è futuro, oggi è un dono...

Diego1981

  • Full Member
  • ***
  • Post: 180
  • Karma: +0/-0
Re:Passare dati a un nuovo thread
« Risposta #9 il: Febbraio 13, 2017, 04:33:23 pm »
allora
usando:
ThrdARequestInfo:=TIdHTTPRequestInfo.Create;
ThrdARequestInfo:=ARequestInfo;

ThrdArequestinfo si valorizza (almeno nell' Analizzatore di debug vedo i parametri inviati dalla pagina html) ma come tento di accede and una proprietà dal thread(per esempio ThrdArequestInfo.Document) e non dalla form principale la classe si vuota completamente

mentre usando
ThrdARequestInfo:=TIdHTTPRequestInfo.Create;
ThrdARequestInfo.Assign(ARequestInfo);

ThrdArequestinfo non si valorizza proprio

PS
ciao xiny provo a copiare due righe in nuovo progetto e le mando, grazie
comunque mi sembra di capire che il threadprincipale finisce la sua procedura (CommandGet in questo caso) e ArequestInfo inviato al costruttore del thread si svuoti/annulla/distrugge (come dir si voglia  :o) e di conseguenza anche tutto il resto sparisce..... ci potrebbe stare?
« Ultima modifica: Febbraio 13, 2017, 05:15:56 pm da Diego1981 »

Diego1981

  • Full Member
  • ***
  • Post: 180
  • Karma: +0/-0
Re:Passare dati a un nuovo thread
« Risposta #10 il: Febbraio 14, 2017, 07:49:45 am »
risolto!!
nomore, approposito di reputazione(la mia), la procedura CommandGet è gia in multithread...azz  :-X

scusate la comfusione

SB

  • Scrittore
  • Sr. Member
  • *****
  • Post: 283
  • Karma: +1/-0
Re:Passare dati a un nuovo thread
« Risposta #11 il: Febbraio 14, 2017, 10:38:03 am »
ThrdARequestInfo:=TIdHTTPRequestInfo.Create;
ThrdARequestInfo:=ARequestInfo;
 :o
stai sovrascrivendo un oggetto appena creato nel thread secondario con un riferimento passato dal thread principale che può non avere alcun significato nel thread secondario...
 :o
mi meraviglio che il debugger faccia vedere qualcosa... probabilmente fa vedere le proprietà dell'oggetto originale fino al refresh della scheda

per funzionare devi creare l'oggetto in memoria condivisa e proteggere l'accesso almeno con una sezione critica

per curiosità, come hai risolto?



xinyiman

  • Administrator
  • Hero Member
  • *****
  • Post: 3270
  • Karma: +12/-0
Re:Passare dati a un nuovo thread
« Risposta #12 il: Febbraio 14, 2017, 11:25:56 am »
SB, sai penso ci sia bisogno di un articoletto su questo tema. Te la senti di scrivere qualcosa con un piccolo esempio, almeno anche per il futuro basterà indicare tale articolo per far capire alle persone dove e come agire!
Ieri è passato, domani è futuro, oggi è un dono...

Diego1981

  • Full Member
  • ***
  • Post: 180
  • Karma: +0/-0
Re:Passare dati a un nuovo thread
« Risposta #13 il: Febbraio 14, 2017, 12:59:16 pm »
Ciao SB
ho risolto rileggendo per la 1000esima volta la procedura CommandGet e provando a mettere uno sleep....ad altre richieste la procedura funzionava perfettamente quindi non c'è bisogno di altri thread
ora però sto litiganto con mysql per il savattaggio dei dati quando ci sono più richieste nello stesso momento da piu pagine (ma questo è un altro problema)
grazie mille comunque

SB

  • Scrittore
  • Sr. Member
  • *****
  • Post: 283
  • Karma: +1/-0
Re:Passare dati a un nuovo thread
« Risposta #14 il: Febbraio 14, 2017, 02:16:26 pm »
Se ho intuito cosa stai facendo...
Attento che lo sleep sospende il thread corrente facendone subentrare un altro, ma è come nascondere la polvere sotto il tappeto... prima o poi il problema salta fuori...
Non ho mai usato la CommandGet, ma se hanno fatto le cose sofisticate e creano un thread separato per ogni richiesta, devi organizzare il codice in maniera tale da risolvere tutto dentro il gestore dell'evento, senza riferimento ad oggetti esterni (es. riferimenti alla connessione al database)
Ricorda che ogni thread "vede" solo ciò che si è creato, e la memoria globale (esplicitamente) condivisa
Gli accessi alla memoria condivisa vanno assolutamente regolati. Il meccanismo più semplice sono le sezioni critiche.
Altra cosa da ricordare è che per questioni di efficienza non tutte le api di sistema o le librerie esterne (es. quelle di accesso ai database) sono previste per il multithreading. Si rischiano dei bei casini.
Bisogna assicurarsi (vedere documentazione, di solito è esplicitamente indicato) che siano multithreading, e se non lo sono bisogna ricorrere ai meccanismi di regolazione disponibili (sezioni critiche, mutex, semafori, ecc)
Infine, per testare il server devi organizzare una batteria di client che vada giù di brutto con le richieste, altrimenti non vedi i possibili problemi e sul più bello si blocca tutto.
Non so se il debugger di Lazarus sia multithreading (mi sembra strano), ma di solito non si riesce a debuggare bene con più thread. Devi ingegnarti a controllare il funzionamento del codice.
Un server è una bella gatta da pelare... buona fortuna...

 

Recenti

How To

Utenti
  • Utenti in totale: 802
  • Latest: Il Faro
Stats
  • Post in totale: 19104
  • Topic in totale: 2279
  • Online Today: 106
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 0
Guests: 104
Total: 104

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.