Когда я пытаюсь создать экземпляр класса с помощью виртуального метода и передать его в pthread_create, я получаю условие гонки, заставляя вызывающего абонента иногда вызывать базовый метод вместо производного метода, как он должен , После googling pthread vtable race
я узнал, что это довольно известное поведение. Мой вопрос: какой хороший способ обойти это?Пробег между виртуальной функцией и pthread_create
Код ниже демонстрирует это поведение при любой настройке оптимизации. Обратите внимание, что объект 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;
}
Просто из любопытства, почему вы объявляете эти «классы» как 'struct's? – mrduclaw
struct означает одно и то же, за исключением того, что все члены общедоступны по умолчанию. –
@mrduclaw: Не беспокойтесь. Это просто прихоть, которую я недавно наблюдал, чтобы использовать * struct * вместо * class *. Это пройдет. :-P –