2012-02-13 4 views
9

In ambienti unix la famiglia di funzioni makecontext()/swapcontext() viene talvolta utilizzata per implementare le coroutine in C. Tuttavia queste funzioni manipolano direttamente lo stack e il flusso di esecuzione. Spesso quando queste funzionalità di basso livello sono abbastanza diverse quando si passa da C a C++.Le funzioni makecontext()/swapcontext() sono compatibili con C++

Quindi la domanda è, se ci sarebbe qualche problema con l'implementazione di coroutine usando makecontext() e swapcontext(). Ovviamente si dovrebbe ovviamente fare molta attenzione, che un'eccezione non potrebbe mai sfuggire a tale coroutine, dal momento che non ci sarebbe alcun gestore di eccezioni in pila per questo e il programma sarebbe molto probabilmente segfault. Ma a parte questo c'è qualche incompatibilità tra il modo in cui C++ gestisce le cose internamente e makecontext() e setcontext() modificare il percorso di esecuzione?

+0

Non avevo mai sentito parlare di queste funzioni. Sei consapevole che [POSIX 2001] (http://pubs.opengroup.org/onlinepubs/009695399/functions/makecontext.html) li ha già contrassegnati come obsolescenti a favore dei thread? –

+6

@larsmans: un peccato. Le cose che sono facili con le coroutine sono molto più difficili con i thread. Sì, è possibile * emulare le coroutine con i thread, ma solo con overhead (sincronizzazione!), E quando un solo thread è in esecuzione in qualsiasi momento con tutti gli altri bloccati, non è proprio ciò che si intende per threading. – celtschk

risposta

6

Ho usato makecontext()/swapcontext() con codice C++ prima e, come dici tu, la cosa principale a cui prestare attenzione sono le eccezioni. Oltre a ciò non ho avuto alcun problema. Nonostante la loro obsolescenza secondo lo standard, sono ancora ben supportati da sistemi operativi unix-like. (c'è un avvertimento per Mac OS X: devi prima di #including le intestazioni pertinenti.) La logica per renderli obsoleti è piuttosto loppa - potrebbero averli sostituiti con una versione simile a pthreads, dove il puntatore della funzione prende un argomento single void *.

Come dici tu, i thread non sono un utile sostituto, quindi andrei avanti e userei swapcontext(). È inoltre possibile trovare this blog post interessante per la rotazione della propria versione delle funzioni.

+0

Post interessante (anche se ritengo che il miglior utilizzo delle coroutine non sia probabilmente per affinamento di tempo o istanze di breve durata, quindi i costi generali citati potrebbero essere il caso peggiore). Ad ogni modo, tanto per aggiungere che evito di lanciare eccezioni e altrimenti non ho problemi nell'usare make/swapcontext (e idem Windows fiber) in un [progetto C++] (http://code.google.com/p/crag/source/browse/ src/smp/FiberPosix.cpp). –