レースと仮想機能pthread_create
-
05-07-2019 - |
質問
私たちはクラスのインスタンスと仮想メソッドですpthread_createを取得し、原因の呼び出し側が、前年同月比を加重平均して算の代わりに由来法のようです。後googling pthread vtable race
, ったことはよく知られる。私の質問は、良い方法です。
以下のコードを示す行動で最適化の設定です。なお、MyThreadオブジェクトが完全に構築される前に渡されpthread_create.
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Thread {
pthread_t thread;
void start() {
int s = pthread_create(&thread, NULL, callback, this);
if (s) {
fprintf(stderr, "pthread_create: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
}
static void *callback(void *ctx) {
Thread *thread = static_cast<Thread*> (ctx);
thread->routine();
return NULL;
}
~Thread() {
pthread_join(thread, NULL);
}
virtual void routine() {
puts("Base");
}
};
struct MyThread : public Thread {
virtual void routine() {
}
};
int main() {
const int count = 20;
int loop = 1000;
while (loop--) {
MyThread *thread[count];
int i;
for (i=0; i<count; i++) {
thread[i] = new MyThread;
thread[i]->start();
}
for (i=0; i<count; i++)
delete thread[i];
}
return 0;
}
解決
唯一の問題は削除するのオブジェの前の芽生のスレッドを実行し、その時間に子デストラクタで焼のオブジェクトはございません。
のではなpthread_createなど、そのタイミングができないのは産卵のスレッドでも資源を残して他はすべて削除する前にその機会を利用します。
そこでどのように、オブジェクト数は破壊によるメインスレッドの前に芽生糸として使用す:
struct Thread {
pthread_t thread;
bool deleted;
void start() {
deleted=false;
int s = pthread_create(&thread, NULL, callback, this);
if (s) {
fprintf(stderr, "pthread_create: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
}
static void *callback(void *ctx) {
Thread *thread = static_cast<Thread*> (ctx);
thread->routine();
return NULL;
}
~Thread() {
pthread_join(thread, NULL);
}
virtual void routine() {
if(deleted){
puts("My child deleted me");
}
puts("Base");
}
};
struct MyThread : public Thread {
virtual void routine() {
}
~MyThread(){
deleted=true;
}
};
その他の手だちな眠りをメインを削除する前にちょいと問題が芽生のスレッドが使を有効な資源です。
int main() {
const int count = 20;
int loop = 1000;
while (loop--) {
MyThread *thread[count];
int i;
for (i=0; i<count; i++) {
thread[i] = new MyThread;
thread[i]->start();
}
sleep(1);
for (i=0; i<count; i++)
delete thread[i];
}
return 0;
}
他のヒント
せんpthread_join(その他のリアルワデストラクタ.追加の参加()メソッドのスレッドを呼び出す前に削除のスレッド[i]main.
しようとした場合に呼pthread_joinにデストラクタ、スレッドがまだ実行 スレッド::通常の().このオブジェクト 既に一部が破壊され.この場合どうなりますか?Java最新にしたら遊べなくなったばプログラムがクラッシュです。
また:
ご希望の場合は継承から、スレッドのスレッド::~スレッドは起動させることができるvirtualなのです。
チェックのためのすべての誤差適切に取り扱い(更新ありができない内部のデストラクタ).
所属していません StackOverflow