Создаю поток с помощью этой функции Код (C): HANDLE handle = 0; DWORD ThreadID; while (handle == 0) { Sleep(100); handle = CreateThread(NULL, 10000, (LPTHREAD_START_ROUTINE)Thread_SyncDATA, (VOID*)&list_process, 0, &ThreadID); CloseHandle(handle); } ....... DWORD WINAPI Thread_SyncDATA(LPVOID lParametr) { бла... бла... бла... } Поток создается при инициализации диалового окна, но происходит это через раз, то создаётся, то нет, причин для такого поведения функции я найти не могу. Перепробывал уже все известные мне варианты записи функции для потока, не чего не помогает.
Дайте угадаю. Процедура в длл-майн. Это значит что происходит гонка потоков, происходит деадлок, поэтому и поведение апп от фазы луны зависит А тс не использует даже отладчик и поэтому запуск и блокировку потока не видит
Кстати, недавно дебажил такую фигню, даже сэмулировал исскуственно. Странная вещь, олли показывает что потоки создаются, но система их не видит (process explorer). Создаются из дллмейн, которая, в свою очередь, загружена из другой дллмейн.
Увы я не силён в "жаргонной" терминологии, знаю main процедуру, процедуру обработки сообщений окна, и dll библиотеки. Буду предполагать, что длл-майн это процедура обработки сообщений окна. Если я всё правильно понял, значит создавать потоки при инициализации диалогового окна нельзя. GetLastError говорит: "Недостаточно памяти для обработки команды". Проверяю, брекпойнт срабатывает в процедуре потока, значит создался, если нет, не создался .
Логика железная. Нет, "длл-маин" это dllmain https://docs.microsoft.com/en-us/windows/desktop/dlls/dllmain Размер стека выставь 0, чтобы дефолтный был и while(handle == 0) убери. Винда конечно кривая, но не настолько чтобы так делать. В цэ не силен, но Thread_SyncDATA я бы на &Thread_SyncDATA махнул на всякий случай. А еще проще собрать пример и выложить, а то методом Кашпировского можно очень долго разбираться в какой-нибудь ерунде.
Механизм обработки гуя довольно сложен. Там тоже есть синхронизации. В принципе значения не имеет - каким образом произошла взаимоблокировка потоков. Даже методом проб, можно найти суть проблемы. Прошли сутки а тс ничего не решил. Не смотря на то, что это самые простые проблемы которые могут быть. CrawlUp, > GetLastError говорит: Смысл той апи - прочитать из среды поле с инфой про ошибку. Но если ошибки нет, то там предыдущее значение, те не корректное. А есчо winerror - коды обьединяют в группы ntstatus. Это утеря инфы, не следует это использовать(винапи коды ошибок). Это инфа ниочём всегда, не ясно даже зачем это реализовано, в каждом случае это приводит к проблеме, заблуждению, а не решает проблему.
Щас довольный собой клерк пойдет на кл за очередным "прошло десять лет ..." Пассажир новичек, он не обязан сразу все знать и уметь.
f13nd, Нет никаких особых требований, но минимальную работу человек должен сделать сам. Хотябы прочитать материал, по фукциям, которые использует. > клерк пойдет на кл Пока там не вычистят всё мне противно туда идти.
Не поленюсь, отвечу . Я работаю на стройке. Двенадцати часовой рабочий день, к планшету могу подойти два раза, это в обед, полчаса и в чай 20 минут. На работу еду в автобусе 2 часа, с работы 1 час. Остаются девять часов на сон, помывку, программирование и тренировку. Хочешь спи, хочешь программируй, так что более 2-3 часов в день выделить на это время я не могу. В выходные там другое дело, минимум 12 часов, но до них надо дожить. Тут я с вами не могу согласится, если ошибки нет GetLastError так и говорит что ошибки нет. А решение я нашёл благодаря вашему совету, просто перенёс создание потока в Main процедуру, добавив в нём лишнюю задержку Sleep. Просто очень странно что в варианте ниже поток не создаётся, но если перед его созданием поставить Sleep задержку то создасться. Код (C): int CALLBACK WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR str_CmdLine, int nCmdShow) { DialogBoxParam(hInst, MAKEINTRESOURCE(ID_DIALOG1), 0, (DLGPROC)WndProc, 0); return true; } ..... /* Обрабатывает сообщения в главном окне :: procesing message in the main window*/ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { _hStatusBar = CreateStatusWindow(WS_VISIBLE + WS_CHILD, 0, hWnd, ID_STATUS); _hListView = CreateWindowExW(0, L"SysListView32", 0, WS_VISIBLE | LVS_REPORT | WS_CHILD | WS_BORDER | LVS_EDITLABELS | WS_EX_CLIENTEDGE, 0, 0, 0, 0, hWnd, (HMENU)ID_LISTVIEW, _hInst, 0); SendMessage(_hListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_ONECLICKACTIVATE); ShowWindow(hWnd, SW_MAXIMIZE); //инициализация объекта хранения и обработки данных list_process.Init(*list_process.Get_PointerTABLE_INFO(),_hListView, process_table); list_process.DrawTable(); handle = CreateThread(NULL, 10000, (LPTHREAD_START_ROUTINE)Thread_SyncDATA, (VOID*)&list_process, 0, &ThreadID); if (handle == 0) { ErrorMessage(); } CloseHandle(handle); ..... case WM_CLOSE: EndDialog(hWnd,0); break; } break; } Не в этом дело, я уже пробовал всякие варианты, в том числе и тот где все нули кроме имени процедуры.
Слип это принудительное переключение на другие потоки, видимо гонка потоков и происходила. --- Сообщение объединено, 12 дек 2018 --- Пока всё за 10 лет не вычистят?
CrawlUp, > Тут я с вами не могу согласится, если ошибки нет GetLastError так и говорит что ошибки нет. Нет, она возвращает предыдущую. На сколько помню трансляция статус в еррор происходит только в случае ошибки. Тогда апдейтится это поле в пеб. Но как бы там небыло не используйте winerror никогда. Иначе у вас всегда и будут не решаемые проблемы. > если перед его созданием поставить Sleep задержку то создасться. Такое быть не может. Поток запускается сразу, он не в гуе(оконной системе) запускается, а в нэйтивном окружении. Это его теневая работа, он сообщает загрузчику о своём создании и затем через перезагрузку контекста покидает загрузчик переходя на вашу заданную процедуру. Вот в ней он и блокируется. Почему предсказать невозможно - у вас в коде асинхронный огород", такой же видимо и в стартап процедуре проблемного потока. У вас рекурсивные вызовы гуя, посылки сообщений и свои синхронизации.. блокировка может быть где угодно. Если задержка снимает проблему, то это и есть та самая ошибка в синхронизации. --- Сообщение объединено, 12 дек 2018 --- CrawlUp, Посмотри сам, это пример из врк, для новой ос соответствия на порядок больше. Код (Text): STATUS_THREAD_IS_TERMINATING, ERROR_ACCESS_DENIED, STATUS_PROCESS_IS_TERMINATING, ERROR_ACCESS_DENIED, STATUS_INVALID_LOCK_SEQUENCE, ERROR_ACCESS_DENIED, STATUS_INVALID_VIEW_SIZE, ERROR_ACCESS_DENIED, STATUS_ALREADY_COMMITTED, ERROR_ACCESS_DENIED, STATUS_ACCESS_DENIED, ERROR_ACCESS_DENIED, STATUS_FILE_IS_A_DIRECTORY, ERROR_ACCESS_DENIED, STATUS_CANNOT_DELETE, ERROR_ACCESS_DENIED, STATUS_INVALID_COMPUTER_NAME, ERROR_INVALID_COMPUTERNAME, STATUS_FILE_DELETED, ERROR_ACCESS_DENIED, STATUS_FILE_RENAMED, ERROR_ACCESS_DENIED, STATUS_DELETE_PENDING, ERROR_ACCESS_DENIED, STATUS_PORT_CONNECTION_REFUSED, ERROR_ACCESS_DENIED, Слева совершенно не связанные статусные(ядерные) коды, которые приводятся к одному дос значению ошибки(winerror, то что возвращает GetLastError()). При этой трансляции происходит утеря инфы и по дос коду ошибки суть не понять. Почему дос" - потому что это понятие разраба, так он в врк сурке написал: --- Сообщение объединено, 12 дек 2018 --- > апдейтится это поле в пеб. в теб разумеется, опечатка. Ввели лимит на редактирование постов, это хорошо!
обычно, если ошибка есть, то функция вернула ошибочное состояние (нулл или инвалих_хендл_валуе), то функция поставила код ошибки... если функция этого не сделала, то это баг в коде мелкомягких... и последний еррор и последний нт статус хранятся в TEB, можно и тот и другой получить... если есть какая-то параноя с этим связанная, то всегда можно руками вызвать SetLastError(0) до вызова функции...
Rel, Статус в теб грузится ядром при обработке исключений вроде бы как, впрочем не важно. Как и говорил следует забыть про getlasterr.
ну если ты не глупенький нт-дрочер, то кодишь на более удобном и простом вин-апи, то без гетластеррор тебе не обойтись... не говоря уже о всяких криптоапи и тд...
Rel, Никогда понимающий как это работает человек такое не посоветует. Ты спалил сам себя, что впрочем не удивительно даже.
как же Инде предполагает обрабатывать ошибки высокоуровневых апи? если Инде предлагает использовать нт-апи для всего, то я предлагаю Инде показать как он будет скажем искать хендл окна по его заголовку, или скажем шифровать данные алгоритмом RSA...
Да обычно этот GetLastError для обработки ошибок не нужен, я например его не использую. Вернула функция не тот статус - сообщаешь об этом и завершаешь функцию вернув своей фукнцией ошибку. А выяснение что там и почему уже вопрос других методов вплоть до тимвивера. Хотя именно при разработке GetLastError бывает полезен, особенно с ком-интерфейсами.