2014-01-24 3 views
1

Как можно убедиться, что параметр потока все еще будет актуальным, когда начнется поток?Актуальность темы темы

ситуация 1:my_thread была создана, но param изменилась сразу же после его создания. Ожидалось бы my_thread, имеющее param_ptr, что указывает на 56, но теперь оно соответствует 89.

DWORD WINAPI my_thread(LPVOID param_ptr); 

int param = 56; 
CreateThread(NULL, NULL, my_thread, &param, NULL, NULL); 
param = 89; 

ситуация 2:my_thread был создан, но param больше не существует, так как create_my_thread уже закрыта.

DWORD WINAPI my_thread(LPVOID param_ptr); 

void create_my_thread(int param) 
{ 
    CreateThread(NULL, NULL, my_thread, &param, NULL, NULL); 
} 

ответ

1

Проходят переменные через кучу и удаления в потоке. Умные указатели могут помочь в том случае, если API их разрешит, в противном случае просто сделайте привычку позволять удалять параметры в функции потока.

DWORD WINAPI my_thread(LPVOID param_ptr); 

int* param = new(56); 
CreateThread(NULL, NULL, my_thread, param, NULL, NULL); 
int newParam = 89; 
+0

спасибо хорошее решение! – Ivars

+0

Я не поклонник ручного управления памятью (новый/удалить), но есть случаи, когда он используется. – stefaanv

+1

BTW: вы можете сделать исключение и передать ints, отбросив его в LPVOID, но я не сторонник, потому что это все еще исключение, и могут быть проблемы с переносимостью, а затем правило всегда удалять параметры в функции потока слабее , – stefaanv

2

Две точки:

  1. Не передвигайте указатель на временную переменную.
  2. Если вы хотите предотвратить изменение первоначального значения, запустите поток как приостановленный, а затем вызовите ResumeThread.

Обратите внимание, что хотя параметр, который вы можете передать функции потока, объявлен как указатель VOID, на самом деле он не должен быть указателем. Так что, если вы просто хотите, чтобы передать некоторое количество (как в вашем примере), вы можете просто бросить его:

CreateThread(NULL, NULL, my_thread, (LPVOID)56, NULL, NULL); 

Затем в функции потока, выполняет обратное преобразование:

DWORD WINAPI my_thread(LPVOID param_ptr) 
{ 
    DWORD dwNumber = (DWORD)param_ptr; 

    // dwNumber is now equal to 56 
} 

Для приостановки и возобновления обратитесь к MSDN для CreateThread options and use CREATE_SUSPENDED`, например:

// create thread but don't start it 
HANDLE hThread = CreateThread(NULL, NULL, my_thread, &param, 
            CREATE_SUSPENDED, NULL); 

// ... make any changes to `param` thst you need your thread to be aware of ... 

// start the thread 
ResumeThread(hThread); 
+0

Это означает, что мне нужно было бы иметь множество глобальных переменных? – Ivars

+0

@ user2543574 Ну, если вы хотите передать что-то в поток, он должен существовать в течение всего времени, когда поток нуждается в нем. Он может быть глобальным, или он может быть локальным, если вы ждете завершения потока в рамках функции. Он также может быть переменной-членом класса. См. Обновленный ответ для другой альтернативы. –

+0

Разве это не убивает многопоточность, так как система не ответит, пока не закончится нить? – Ivars

Смежные вопросы