次のマネージャー<->ワーカーの状況があります。
class Manager {
private:
pthread_attr_t workerSettings;
pthread_t worker;
pthread_cond_t condition;
pthread_mutex_t mutex;
bool workerRunning;
static void* worker_function(void* args) {
Manager* manager = (Manager*)args;
while(true) {
while(true) {
pthread_mutex_lock(&manager->mutex);
if(/* new data available */)
{
/* copy new data from shared to thread memory */
pthread_mutex_unlock(&manager->mutex);
}
else
{
pthread_mutex_unlock(&manager->mutex);
break;
}
/* process the data in thread memory */
pthread_mutex_lock(&manager->mutex);
/* copy results back to shared memory */
pthread_mutex_unlock(&manager->mutex);
}
pthread_mutex_lock(&manager->mutex);
// wait for new data to arrive
while(manager->workerRunning && !/* new data available*/)
pthread_cond_wait(&manager->condition, &manager->mutex);
// check if we should continue running
if(!manager->workerRunning)
{
pthread_mutex_unlock(&manager->mutex);
break;
}
pthread_mutex_unlock(&manager->mutex);
}
pthread_exit(NULL);
return NULL; // just to avoid the missing return statement compiler warning
}
public:
Manager() : workerRunning(true) {
pthread_cond_init(&condition, NULL);
pthread_mutex_init(&mutex, NULL);
pthread_attr_init(&workerSettings);
pthread_attr_setdetachstate(&workerSettings, PTHREAD_CREATE_JOINABLE);
pthread_create(&worker, &workerSettings, worker_function, (void*)this);
}
// this *may* be called repeatedly or very seldom
void addData(void) {
pthread_mutex_lock(&mutex);
/* copy new data into shared memory */
pthread_cond_signal(&condition);
pthread_mutex_unlock(&mutex);
}
~Manager()
{
// set workerRunning to false and signal the worker
pthread_mutex_lock(&mutex);
workerRunning = false;
pthread_cond_signal(&condition);
pthread_mutex_unlock(&mutex);
// wait for the worker to exit
pthread_join(worker, NULL);
// cleanup
pthread_attr_destroy(&workerSettings);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condition);
}
};
これについては、いくつかの場所で完全にはわかりません。
- Manager がそのコンストラクターで新しいスレッドを生成するという事実は、悪い習慣と見なされますか? (私は Manager オブジェクトを 1 つしか持たないので、それで問題ないと思います)
- pthread_exit についてはどうですか - これは多くのチュートリアルで見られますが、なぜそこにあるのかよくわかりません。関数を返してスレッドを終了することはできませんか? また、リターン NULL はデッド コードだと思いますが、gcc は、その時点で pthread_exit が既にスレッドを強制終了したことを明らかに認識できないため、欠落している場合に警告します。
- コンストラクターについて - スレッドを生成した直後にスレッド属性オブジェクト (workerSettings) を破棄できますか、それともスレッドの存続期間全体にわたって有効である必要がありますか?
- デストラクタについて: これは正しい方法ですか?
最も重要な:
- あなたの経験豊富な目で同期の問題が見られますか?
ご協力いただきありがとうございます!