#cpp #многопоточность
Здравствуйте!
У меня есть 2 глобальных массива static TCHAR abc[32+1]; и static TCHAR defa[32+1];,
объявлены в главном cpp, сразу после includ-ов.
Есть главная ф-ия, которая в свою очередь запускает функцию start():
//Main.cpp
void WINAPI entryPoint() {
start();
while (true) { Sleep(3000); MessageBox(0,abc,0,0);}
}
Функция start заполняет массив определенным содержанием, а дальше запускает ф-ию(startThread),
которая находится уже в другом файле cpp, которая в свою очередь запускает поток с
помощью CreateThread:
//Main.cpp
bool start() {
lstrcpy(abc, _T("Hello"));
lstrcpy(defa, _T("How are you?"));
startThread(abc);
MessageBox(0,_T("Завершить функцию start?"));
}
//Thread.cpp
struct PARAMS{
TCHAR *abc;
TCHAR *defa;
}
void startThread(TCHAR *abc, TCHAR *defa) {
PARAMS arr = { abc, defa };
CreateThread(NULL, 0, &threadfunction, &arr, 0, NULL);
}
Сама функция потока выглядит так:
//Thread.cpp
DWORD WINAPI threadfunction(LPVOID arr) {
PARAMS*PARR= (PARAMS*)arr;
while (true) {
MessageBox(0, PARR->abc, L"Thread 2", 0);
MessageBox(0, PARR->defa, L"Thread 2", 0);
}
}
Проблема в том, что после того как завершается функция bool start() в главном потоке,
из abc и defa исчезают значения и поток начинает выдавать пустые сообщения, я не понимаю
почему это происходит. При чем, если не завершать функцию start(), т.е. не закрывать
мессагу MessageBox(0,_T("Завершить функцию start?"));, то все нормально. Из главного
потока я по прежнему имею доступ к этим переменным, даже после завершения start(),
т.е. вот тут все нормально продолжает работать while (true) { Sleep(3000); MessageBox(0,abc,0,0);}
Реализация на чистом WinApi, так что, другие варианты создания потоков не рассматриваю.
Ответы
Ответ 1
void startThread(TCHAR *abc, TCHAR *defa) { PARAMS arr = { abc, defa }; CreateThread(NULL, 0, &threadfunction, &arr, 0, NULL); } В любом случае передавать в функцию потока адрес локального объекта arr - очень нехорошо. Поток еще и запуститься как следует не успевает, а выделенная под arr память уже недействительна...Ответ 2
после "PARAMS arr = { abc, defa }; CreateThread(NULL, 0, &threadfunction, &arr, 0, NULL);" надо подключиться к потоку и дождаться его завершения или PARAMS на new и освобождать внутри потока.Ответ 3
Можно сделать так: void startThread(TCHAR *abc, TCHAR *defa) { PARAMS arr = new PARAMS{ abc, defa }; CreateThread(NULL, 0, &threadfunction, arr, 0, NULL); } И вызывать деструктор в функции потока. Еще лучше сделать так: void startThread(TCHAR *abc, TCHAR *defa) { std::thread thread{ [abs, defa]{ while (true) { MessageBox(0, abc, L"Thread 2", 0); MessageBox(0, defa, L"Thread 2", 0); } // delete[] abs; deletee[] defa; // Кто-то должен освобождать память, но цикл бесконечный. }}; thread.detach(); // Отпускаем поток в свободное плаванье. Ну или ждем завершения при помощи thread.join(); } Кроме того, по хорошему нужно завершить поток до завершения программы, т.к. иначе не все деструкторы будут вызваны. Ресурсы система, конечно, освободит, но в реальных проектах может потребоваться выполнить дополнительные действия, например, запись в log файлы. Для этого можно использовать механизм событий, или банально общие атомарные переменные (посмотрите в сторону std::atomic). Тогда вместо while(true) будет while(cond), и после завершения цикла можно освобождать ресурсы и совершать другие действия.
Комментариев нет:
Отправить комментарий