thread_specific_ptr многопоточная путаница

// фрагмент кода 1

static boost::thread_specific_ptr<StreamX> StreamThreadSpecificPtr;
void thread_proc() {
StreamX * stream = NULL;
stream = StreamThreadSpecificPtr.get();
if (NULL == stream) {

stream = new StreamX();
StreamThreadSpecificPtr.reset(stream);
}
printf("%p\n", stream);
}
int run() {
boost::thread_group threads;
for(int i = 0; i < 5; i ++) {
threads.create_thread(&thread_proc);
}
threads.join_all();
}

// the result is
0x50d560  -- SAME POINTER
0x50d540
0x50bfc0
0x50bef0
0x50d560  -- SAME POINTER

// фрагмент кода 2

static boost::thread_specific_ptr<StreamX> StreamThreadSpecificPtr(NULL); // DIFF from code snippet 1
void thread_proc() {
StreamX * stream = NULL;
stream = StreamThreadSpecificPtr.get();
if (NULL == stream) {

stream = new StreamX();
StreamThreadSpecificPtr.reset(stream);
}
printf("%p\n", stream);
}
int run() {
boost::thread_group threads;
for(int i = 0; i < 5; i ++) {
threads.create_thread(&thread_proc);
}
threads.join_all();
}

// the result is
0x50d510
0x50d4f0
0x50bf70
0x50ca70
0x50be50

В фрагменте кода 1 два указателя совпадают. это не ожидается.
Во фрагменте кода 2 с инициализацией StreamThreadSpecificPtr равным NULL все выглядит хорошо.

Не могли бы вы помочь выяснить ответ на эту путаницу? Большое спасибо.

1

Решение

Радость в том, что ваши потоки фактически завершаются асинхронно, разрушая экземпляры StreamX.

Используя детектор:

struct StreamX
{
StreamX() { puts(__FUNCTION__); }
~StreamX() { puts(__FUNCTION__); }
};

Я получаю следующий вывод:

StreamX
0x7f258c0008c0
~StreamX
StreamX
0x7f25740008c0
~StreamX
StreamX
0x7f25840008c0
~StreamX
StreamX
0x7f25780008c0
StreamX
~StreamX
0x7f257c0008c0
~StreamX

real    0m0.002s
user    0m0.000s
sys 0m0.004s

Для последующих распределений имеет смысл повторно использовать одни и те же адреса кучи, поскольку фрагментации не так много. Другими словами, вы не можете просто сравнить указатели, чтобы увидеть, являются ли они псевдонимами одного и того же объекта в параллельном приложении.

Разница со вторым примером только ложная. Есть много факторов, которые могут — и будут — влиять на результат. Например. добавление крошечной задержки в конце каждого потока исключит возможность завершения потоков до того, как будут созданы другие экземпляры.

Видеть это Жить на Колиру

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]