#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), и после завершения цикла можно освобождать ресурсы и совершать другие действия.
Комментариев нет:
Отправить комментарий