Tworzenie wątku w WM_CREATE

0

Cześć.
Mam następujący problem. Mam funkcję wątku, w której co 1 sekundę wczytuję jakąś zmienną. W funkcji jest zastosowana pętla nieskończona i sleep(1000). Generalnie coś takiego:

DWORD funkcja(LPVOID param) {
   while(TRUE) {
      // ...
      Sleep(1000);
   }
}

Uruchomienie nowego wątku umieszczam w obsłudze komunikatu WM_CREATE. Przy tak wywołanej funkcji program uruchamia mi się jakieś 30 sekund. Jeśli w tym komunikacie umieszczę funkcję bez pętli nieskończonej, lub powyższą funkcję uruchomię dopiero później gdzieś w programie, wszystko działa bez zarzutu.
Szukałem trochę na ten temat po forach, ale generalnie mało konkretnych rzeczy znalazłem.
Dzięki za pomoc.

0

nie dostaniesz sensownej odpowiedzi...

czemu? wyjaśnienie: bo coś spierniczyłeś, coś namotałeś przy opisywaniu tego i jeszcze, podałeś funkcje wątku, ale co z tego?
pokaż wszystkie biorące udział w problemie fragmenty kodu, a nie sobie jaja robisz...

0

Funkcja jest dowolna uruchamiana w drugim wątku przy komunikacie WM_CREATE. Najprościej to wygląda w ten sposób:

#include <windows.h>

char szClassName[] = "WindowsApp";
const int xOkno = 600;
const int yOkno = 400;
const char tytulOkno[] = "Aplikacja";
HANDLE watek;
DWORD wsk;

DWORD Funkcja(LPVOID param) {
	while(TRUE) {
		Sleep(1000);
	}
	return 0;
}

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hThisInstance,
					HINSTANCE hPrevInstance,
					LPSTR lpszArgument,
					int nFunsterStil)
{
	HWND hwnd;
	MSG messages;
	WNDCLASSEX wincl;
	wincl.hInstance = hThisInstance;
	wincl.lpszClassName = szClassName;
	wincl.lpfnWndProc = WindowProcedure;
	wincl.style = CS_DBLCLKS;
	wincl.cbSize = sizeof (WNDCLASSEX);
	wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
	wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
	wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
	wincl.lpszMenuName = NULL;
	wincl.cbClsExtra = 0;
	wincl.cbWndExtra = 0;
	wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
	if (!RegisterClassEx (&wincl))
		return 0;
	hwnd = CreateWindowEx(0, szClassName, tytulOkno,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, xOkno+8, yOkno+34,
		HWND_DESKTOP, NULL, hThisInstance, NULL);
	ShowWindow (hwnd, nFunsterStil);
	while (GetMessage (&messages, NULL, 0, 0))
	{
		TranslateMessage(&messages);
		DispatchMessage(&messages);
	}
	return messages.wParam;
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_CREATE:
			watek = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Funkcja, hwnd, 0, & wsk);
			break;
		case WM_DESTROY:
			PostQuitMessage (0);
			break;
		default:
			return DefWindowProc (hwnd, message, wParam, lParam);
	}
	return 0;
}

Kompilator DevCpp 4.9.9.2. Przy dowolnej funkcji z pętlą nieskończoną uruchamianą w ten sposób program uruchamia mi się 30 sekund, bez względu czy pozostała część programu jest długa czy krótka.
I drugie pytanie: tak ciężko normalnie powiedzieć, żeby wkleić kod programu? Na przykład: "czy mógłbyś wkleić kod programu bo nie wiem o co ci chodzi?". I nie robię sobie jaj, tylko proszę o pomoc. Dzięki z góry i sorry jak uraziłem.
Pozdrawiam.

0

Piaggio, Twoim zadaniem jest dostarczenie wystarczających i zwięzłych informacji. Trzeba napisać co i jak robisz, albo wkleić kawałki kodu w których widać jak coś robisz.
Kod który podałeś, u mnie wchodzi do normalnego stanu natychmiast po uruchomieniu. W funkcji Funkcja musisz robić coś, co blokuje oba wątki. Albo to nam pokażesz co takiego robi Funkcja, albo w debuggerze wyłap moment zawieszenia się programu i zerknij na czym wiszą oba wątki, w jakich funkcjach (callstack), oraz jaki ostatni LOG wypluła funkcja Funkcja:

OutputDebugString("wysyłam komunikat xx"); // albo dprintf(...); z dprintf.h
SendMessage();
OutputDebugString("gotowe");

Albo lepiej:

if (!SendMeesageTimeout(hwnd,xx,wparam,lparam,SMTO_ABORTIFHUNG,5000,&result))
   MessageBox(0, "Funkcja: okno nie odpowiada na komunikat xx",0,0)

Niekiedy lepiej jest użyć funkcji QueueUserAPC() by uruchomić dowolną funkcję w kontekście dowolnego wątku, niż wysyłać komunikaty z pobocznego wątku. Jednak wymaga to przerobienia pętli z GetMessage na cos całkiem innego: MsgWaitForMultipleObjectsEx (poniżej). Czasem taka przeróbka znacznie przyspiesza wysłanie serii komunikatów z pobocznego wątku.

HANDLE g_hMainThread;

main()
{
	DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(),
		&g_hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS);

// otwórz okno

	HANDLE hEvent = CreateEvent(0,0,0,0);
	while (okno jest otwarte)
	{
		DWORD status = MsgWaitForMultipleObjectsEx(1, &hEvent, 5000, QS_ALLINPUT, MWMO_ALERTABLE);
		if (status == 1)
		{
			while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
			{
				// if !TranslateAccelerator ... !IsDialogMessage ... !TranslateMDISysAccel
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
	}
	CloseHandle(hEvent);
	CloseHandle(g_hMainThread);
//Dodanie APC do kolejki: (z pobocznego wątku)
QueueUserAPC((PAPCFUNC)APCProc1, g_hMainThread, parametr);
// czekaj na wykonanie?
// if (WaitForSingleObject(parametr->hEvent, czas) == WAIT_TIMEOUT) error("...");

VOID CALLBACK APCProc1(JAKAS_STRUKTURA *parametr)
{
	// to się wykonuje w kontekście głównego wątku
	... cośtam
	// potwierdź zakończenie?
	// SetEvent(parametr->hEvent);
}
0

Ten kod jest właśnie całym programem. Do wygenerowanego przez DevCpp dodałem ze cztery linijki i nic więcej. Powyższy program totalnie nic nie robi, a uruchamia mi się minutę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1