Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [C++] Delete di un oggetto da + thread

    Salve ragazzi,
    avrei un dubbio a proposito di un problema riguardo al delete di un oggetto che potrebbe avvenire anche in contemporanea da + thread.

    Il progettino è un semplice programmino client-server TCP tramite i winsock (quindi su windows).
    Utilizzo select() per la comunicazione e quindi un'architettura ad eventi. Ho un thread separato dove eseguo la select sui vari socket (il socket del server ed X client connessi al server). Il server mantiene una sua lista di client connessi.

    La questione che non capisco come gestire al meglio è il momento della chiusura della connessione del client. Cioè:
    - ho il thread della select che, in caso riceva una notifica di chiusura del client, richiama client->close() che andrebbe a chiudere la socket di connessione del client e dovrebbe fare il delete dell'oggetto Socket del client.
    - quando il server viene chiuso, il server fa sempre client->close() su tutti i suoi client in lista che chiude la socket di connessione del client e dovrebbe fare il delete dell'oggetto Socket del client.

    Quando chiudo il server ed un client notifica la disconnessione nello stesso momento della chiusura del server, 2 thread cercano di fare client->close() e spesso si verifica un seg fault perchè ovviamente entrambi fanno il delete e quello che lo fa per secondo va a cancellare un oggetto già cancellato.

    Secondo voi come posso fare a "sincronizzare" i 2 delete..? probabilmente dovrei tenere un flag fuori dall'oggetto così da capire se l'oggetto è stato già deletato e non cancellarlo di nuovo ma mi sembra schifosa come soluzione. Non è una domanda "tecnica" sulla programmazione, piu' che altro chiedo un consiglio sul design..

    grazie in anticipo
    Ultima modifica di lolide; 05-01-2014 a 17:21
    lolide
    Java Programmer

    Informati

  2. #2
    Mi lascia perplesso il fatto che a questi oggetti si acceda in maniera così disinvolta dai due thread... devi stabilire per ogni oggetto (1) chi è l'oggetto "proprietario" (che si occupa della sua cancellazione) e (2) in che thread "vive" (o almeno, in che thread nasce e muore). Mischiare tutto in questa maniera non ti può dare che problemi.

    Nello specifico, perché il server fa client->close() se già ci pensa l'altro thread quando riceve la notifica di disconnessione?
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Potresti usare una logica simile ogni thread decrementa un contatore alla cancellazione e solo quando vale 0 cancelli l'oggetto. Naturalmente il contatore viene incrementato ad creazione.
    Per gli Spartani e Sparta usa spartan Il mio github

  4. #4
    Be' se vuoi usare uno schema di reference counting allora semplicemente usa uno smart pointer tipo std::shared_ptr (disponibile da C++11 in poi) o boost::shared_ptr (identico, ma utilizzabile in revisioni precedenti del C++).
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Quote Originariamente inviata da linoma Visualizza il messaggio
    Potresti usare una logica simile ogni thread decrementa un contatore alla cancellazione e solo quando vale 0 cancelli l'oggetto. Naturalmente il contatore viene incrementato ad creazione.
    Il fatto è che non è detto che il client chiuda la connessione al server... avendo 2 thread che ci accedono, mi dovrei aspettare 2 chiamate al close(), ma se il client lato suo non richiede la chiusura della connessione il client->close() dal thread della select non arriverà mai e non farà mai il delete...

    Quote Originariamente inviata da MItaly Visualizza il messaggio
    Mi lascia perplesso il fatto che a questi oggetti si acceda in maniera così disinvolta dai due thread... devi stabilire per ogni oggetto (1) chi è l'oggetto "proprietario" (che si occupa della sua cancellazione) e (2) in che thread "vive" (o almeno, in che thread nasce e muore). Mischiare tutto in questa maniera non ti può dare che problemi.

    Nello specifico, perché il server fa client->close() se già ci pensa l'altro thread quando riceve la notifica di disconnessione?
    Hai ragione.
    Il problema di gestire tutto da un solo thread è che mi porterebbe a scegliere:
    - Il delete del socket si fa SOLO se il client richiede la disconnessione, quindi dal thread della select().
    - SOLO al momento della chiusura del server, quindi dal thread principale che gestisce il server.

    Per la prima, non vorrei obbligare il client ad eseguire la disconnessione prima di fare lo shutdown del server.
    Per la seconda, se il mio server rimanesse in vita per tanto tempo e si connettessero tanti client, dovrei tenere in memoria gli oggetti di ogni client anche se ormai si è disconnesso fino a quando il server rimane up. A meno di fare qualcosa che ad intervalli pulisca questa lista...
    lolide
    Java Programmer

    Informati

Tag per questa discussione

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.