Abgesehen von den fehlenden Rückgabewertprüfungen gibt es noch einige weitere Probleme, die behoben werden sollten:
sem_destroy
wird nicht aufgerufen.- Signal/Durchsage berühren Sie die
cond_node_t
nach dem Aufwecken des Zielthreads, was möglicherweise zu einem Use-after-free führt.
Weitere Kommentare:
- Die ausgelassene Zerstörungsoperation kann Änderungen an den anderen Operationen erfordern, so dass es sicher ist, die Bedingungsvariable zu zerstören, wenn POSIX sagt, dass sie sicher sein soll. Destroy nicht zu unterstützen oder stärkere Beschränkungen auferlegen, wann es aufgerufen werden darf, wird die Dinge vereinfachen.
- Eine Produktionsimplementierung würde den Thread-Abbruch handhaben.
- Rückzug aus einer Wartezeit (z. B. erforderlich für Thread-Abbruch und
pthread_cond_timedwait
Timeouts) kann zu Komplikationen führen. - Ihre Implementierung stellt Threads im Userland in die Warteschlange, was in einigen Produktionsimplementierungen aus Leistungsgründen geschieht; Ich verstehe nicht genau warum.
- Ihre Implementierung stellt Threads immer in LIFO-Reihenfolge in die Warteschlange. Dies ist häufig schneller (z. B. aufgrund von Cache-Effekten), kann jedoch zu Hunger führen. Die Produktionsimplementierung kann manchmal die FIFO-Reihenfolge verwenden, um Hunger zu vermeiden.
Grundsätzlich sieht Ihre Strategie in Ordnung aus, aber Sie haben eine große Gefahr, ein undefiniertes Verhalten und einen Nitpick:
- Sie untersuchen nicht die Rückgabewerte Ihrer POSIX-Funktionen. Insbesondere
sem_wait
ist unterbrechbar, so dass Ihr Thread unter hoher Last oder Pech fälschlicherweise aufgeweckt wird. Das alles müsstest du sorgfältig einfangen - Keine Ihrer Funktionen gibt einen Wert zurück. Wenn einige Benutzer der Funktionen eines Tages entscheiden, die Rückgabewerte zu verwenden, ist dies ein undefiniertes Verhalten. Analysieren Sie sorgfältig die Fehlercodes, die die Bedingungsfunktionen zurückgeben dürfen, und tun Sie genau das.
- geben Sie die Rückgabe von
malloc
nicht um odercalloc
Bearbeiten: Eigentlich brauchen Sie malloc
nicht /free
überhaupt. Eine lokale Variable würde es auch tun.