Domanda

Diciamo che ho un contenitore (std :: vector) di puntatori usato da un'applicazione multi-thread. Quando si aggiungono nuovi puntatori al contenitore, il codice è protetto usando una sezione critica (boost :: mutex). Tutto bene. Il codice dovrebbe essere in grado di restituire uno di questi puntatori a un thread per l'elaborazione, ma un altro thread separato potrebbe scegliere di eliminare uno di questi puntatori, che potrebbe essere ancora in uso. per esempio:.

thread1()
{
    foo* p = get_pointer();
    ...
    p->do_something();
}

thread2()
{
    foo* p = get_pointer();
    ...
    delete p;
}

Quindi thread2 potrebbe cancellare il puntatore mentre thread1 lo sta usando. Nasty.

Quindi, invece, voglio usare un contenitore di ptrs condivisi Boost. IIRC questi puntatori verranno conteggiati come riferimento, quindi finché restituisco ptr condivisi anziché puntatori non elaborati, rimuovendone uno dal contenitore NON lo libereremo fino all'ultimo utilizzo. cioè.

std::vector<boost::shared_ptr<foo> > my_vec;

thread1()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    sp->do_something();
}

thread2()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    my_vec.erase(my_vec.begin());
}

boost::shared_ptr<foo> get_ptr(int index)
{
    lock_my_vec();
    return my_vec[index];
}

Nell'esempio sopra, se thread1 ottiene il puntatore prima che le chiamate thread2 vengano cancellate, l'oggetto puntato sarà ancora valido? In realtà non verrà eliminato al termine di thread1? Nota che l'accesso al vettore globale avverrà tramite una sezione critica.

Penso che questo sia il modo in cui shared_ptrs funziona ma devo esserne sicuro.

È stato utile?

Soluzione

Per la sicurezza del threading di boost :: shared_ptr è necessario selezionare questo link . Non è garantito per essere sicuro, ma su molte piattaforme funziona. La modifica di std :: vector non è sicura AFAIK.

Altri suggerimenti

  

Nell'esempio sopra, se thread1 ottiene il puntatore prima che le chiamate thread2 vengano cancellate, l'oggetto puntato sarà ancora valido? In realtà non verrà eliminato al termine di thread1?

Nel tuo esempio, se thread1 ottiene il puntatore prima di thread2, thread2 dovrà attendere all'inizio della funzione (a causa del blocco). Quindi, sì, l'oggetto indicato sarà ancora valido. Tuttavia, potresti voler assicurarti che my_vec non sia vuoto prima di accedere al suo primo elemento.

Se in aggiunta, sincronizzi gli accessi al vettore (come nella tua proposta di puntatore non elaborato originale), il tuo utilizzo è sicuro. Altrimenti, potresti cadere nel fallo dell'esempio 4 nel link fornito dall'altro intervistato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top