_beginthread



  • Hallo,

    habe das Problem, dass er den Bezeichner nicht erkennt "_beginnthread" auch wenn ich process.h einbinde. Habe mir auch das neue SDK runtergeladen (auch eingebunden).. trotzdem geht nix. Was mache ich falsch?

    Noch 2 Fragen:

    Wenn ich einen Thread mit CreateThread aufrufe..

    thead()
    {
      machedies()
    
      return 0;
    }
    

    arbeitet er dann komplett die Funktion "machedies()" ab und springt fann raus..oder fängt er an mit der Funktion an und springt sofort raus, da ein return 0 danach kommt?

    Habe vieles gelesen zum Thema Thread beenden. Wie beendet man richtig? Einfach auslaufen lassen? CloseHandle()? TerminateThread()?

    Danke danke!



  • zu 1) project-settings auf multithreading stellen /MT
    zu 2) ja, wird komplett abgearbeitet
    zu 3) _beginthreadex() benutzen und mit WaitForSingleObject() auf "sauberes auslaufen" warten, danach CloseHandle() ...



  • Danke erstmal,

    der Befehl wird nun erkannt.. jedoch kommt es beim Aufruf zu folgendem Fehler..
    "not enought space for Thread data"

    unsigned __stdcall WnSckConnect(void* pVoid)
    ..
    m_hserverconThread = (HANDLE)_beginthreadex(NULL, 0, &WnSckConnect, NULL, 0, &uThreadId);
    

    ..

    unsigned __stdcall WnSckConnect(void* pVoid)
    {
    	m_socket=accept(m_socket_accept,NULL,NULL);
    	init();
    
    	return 0;
    }
    

    habe ich bei _beginthreadex falsche Parameter übergeben?!?!



  • m_hserverconThread = (HANDLE)_beginthreadex(NULL, 0, &WnSckConnect, NULL, 0, &uThreadId);
    

    nimm mal das "&" bei WnSckConnect raus ...



  • immer noch der selbe Fehler 😞



  • kriegst du den fehler als run-time oder schon während des compilens ?

    übrigens ist bei WinX die standard-stack size auf 1MB eingestellt - belegst du mehr innerhalb des threads ? zb bei init() ? dann musst du die stack-size manuell erhöhen ->2. parameter.



  • das ist ein Runtime Error wenn ich als Server auf "Server starten" klicke.

    in Init werden so Sachen wie hier gemacht:

    WSAAsyncSelect(m_socket, m_hwnd, WM_WINSOCK, FD_READ|FD_WRITE|FD_ACCEPT|FD_CONNECT|FD_CLOSE);
    
             // send(socket, ..)
    	SendNetMessage("",m_user.GetUserName());
    ..
    

    und es werden Buttons erstellt (Handles in einem Array gespeichert) CreateWindow("button"..) etc.
    Also es passiert schon was.

    ich finde leider keine Beschreibung in der MSDN über _beginthreadex .. was muss ich als 2 Param angeben, wenn ich stacksize erhöhen will?



  • also wenn du nicht gerade irgendwo ein "int x[20000000]" hast sollte die stack-size ok sein. es zählen ja nur fest angelegte variablen und keine, die mit new auf dem heap erzeugt werden. deshalb wäre ich vorsichtig damit, den wert einfach aufzubohren, da du damit deinen eigentlichen fehler verdecken könntest. man macht das übrigens, indem man seinen gewünschten stack-wert einfach als UINT im 2. parameter übergibt, aber ...

    der fehler liegt 100% sicher woanders. da hilft jetzt nur DEBUGGER anwerfen, BP in der thread-function setzen und "steppen" bis F10 und F11 qualmen. eine fern diagnose ist hier wirklich schwierig.



  • das Problem, er stürzt vor der Thread funktion ab.
    _beginthreadex macht er ohne Probleme, aber er kommt nicht in die Thread Funktion und wenn ich bei _beginthread ein BP setze, dann kann ich bin ins nichts debuggen



  • poste mal deinen code ...



  • schon mal gesehen, was ms dazu sagt ... seltsam, vielleicht ein fehler in deinem setup ?

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/R6016.asp



  • int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow )
    {
    	HWND		hWnd;
    	MSG			msg;
    	WNDCLASSEX	wc;
    
    	const char szAppName[] = "WindowClass";
    	// Fensterklassen struktur wird gefüllt
    	wc.style			= CS_HREDRAW | CS_VREDRAW;
    	wc.cbSize			= sizeof(WNDCLASSEX);
    	wc.lpfnWndProc		= WndProc;
    	wc.cbClsExtra		= 0;
    	wc.cbWndExtra		= 0;
    	wc.hInstance		= hInstance;
    	wc.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
    	wc.hIconSm			= LoadIcon(NULL, IDI_APPLICATION);
    	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground	= (HBRUSH)(COLOR_BTNFACE + 1);
    	wc.lpszMenuName		=	NULL;
    	wc.lpszClassName	= szAppName;
    	wc.cbClsExtra		= 0; 
    	wc.cbWndExtra		= 0; 
    
    	// Klasse wird registriert
    	RegisterClassEx(&wc);
    
    	// Fenster wird erstellt
    	hWnd = CreateWindowEx(NULL,
    						 szAppName,
    						 "",
    						 WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX | WS_SIZEBOX),
    						 CW_USEDEFAULT,
    						 CW_USEDEFAULT,
    						 640,
    						 480,
    						 NULL,
    						 NULL,
    						 hInstance,
    						 NULL );
    
    	ShowWindow(hWnd, iCmdShow);
    	UpdateWindow(hWnd);
    
    	m_hwnd=hWnd;
    
    	// SplashScreen wird angezeigt
    	ShowSplash();
    
    	while(GetMessage(&msg, NULL, 0, 0) > 0)
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	return msg.wParam;
    }
    
    -------------------------
    -------------------------
    
    BOOL CALLBACK SplashScreenProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
    {      
    	switch (message) 
             {
    ...
    
    	case IDC_BUTTON_START:
    	{
                  ...
                  m_hserverconThread = (HANDLE)_beginthreadex(0, NULL,  WnSckConnect, (void*)0, 0, 0); 
             }
             break;
             }
    
    return false; 
    }
    -------------------------
    -------------------------
    
    unsigned __stdcall WnSckConnect(void* pVoid)
    {
    	m_socket=accept(m_socket_accept,NULL,NULL);
    	Init();
    
    //	_endthreadex(0);
    	return 0;
    }
    
    -------------------------
    -------------------------
    
    void Init()
    {
    	if(m_socket==INVALID_SOCKET)
    	{
    		MessageBox(m_hwnd,"Server -> accept() -> INVALID_SOCKET","Fehler",NULL);
    		return;
    	}
    
    	WSAAsyncSelect(m_socket, m_hwnd, WM_WINSOCK, FD_READ|FD_WRITE|FD_ACCEPT|FD_CONNECT|FD_CLOSE);
    
    	// Feld wird initialisiert
    	m_playfield.Init(3,3,&m_hwnd);
    	m_playfield.DrawField(360,120);
    
    	if(m_serverclient == STARTAS_SERVER)
    	{
    		int fliprandomnr,
    			randomnr;
    
    		// Playernummer (Wer fängt an) wird durchs Zufallsprinzip vergeben
    		time_t t; 
    		time(&t); 
    		srand((unsigned int) t); 
    		randomnr = (int)rand() % 2; 
    
    		// Player Symbol X oder O
    		m_player.SetPlayerSymbol(randomnr);
    		fliprandomnr = randomnr==0?1:0;
    		SendNetMessage(SEND_PLAYERSYMBOL,fliprandomnr);
    
    		if(fliprandomnr==1)
    		{
    			m_myturn=false;
    			SetStatusText("Ihr Mitspieler ist am Zug");
    
    			SendNetMessage(SEND_TURNISOVER);
    
    		}
    		else
    		{
    			m_myturn=true;
    			SetStatusText("Sie sind am Zug");
    		}
    	}
    
    	EndDialog(m_hSplashScreen, 0);
    }
    

    das ist so das wichtigste denke ich mal.. er erreicht den Thread nicht und kommt dementsprechend auch nicht bei Init() an..

    und danke für deine Hilfe!



  • Also nach dem Beispiel in der Doku muss es schon &WnSckConnect heißen und nicht WnSckConnect 🙄



  • Woher kommen die ganzen Variablen (m_socket_accept,m_hwnd,m_socket,etc.), die du in WnSckConnect und Init verwendest? Sind die global?



  • also ich habe da noch was gefunden:

    die runtime-lib legt so eine database für threads an. diese wird möglicherweise auch in der swap-datei deines os gespeichert. kann es sein, dass da der platz auf der platte dem ende zugeht ? check das mal ...

    in google bekommst du viele ergebnisse, wenn du nach diesem error suchst. die vermutung liegt fast nahe, dass es nicht an deinem prog liegt.



  • @RockNix: ich habe noch auf jeder Platte ca 8 GB frei.. denke das sollte reichen

    @flenders:
    m_socket_accept etc. sind zur Zeit Global (Typ SOCKET).. sind auch alle in Ordnung. Das Problem ist, das er nicht mal in die Threadfunktion springt und m_socket = accept(..); ausführt (beim BreakPoint bleibt er nicht stehen)

    Ich habe diese thread Sache eingebaut, weil ich den Server vom accept() zustand wegbekommen wollte, da sonst alles nur hängt. Vorher ging auch alles, hab nur m_socket = accept(...); in den Thread gepackt.. mit CreateThread gings auch.. aber Fehlerhaft, da er das m_playfielf.DrawField usw ausgeführt hat, aber es passierte nichts. Wenn ich diese funktion ausserhalb des Threads gestartet habe dann ging alles super.

    ich werd mal neustarten.. nicht das es am OS liegt...



  • geht immer noch nicht ...

    "R6016 - Not enough Space for thread data"

    wenn ich dann auf Retry drücke kommt das bekannte Ordnerdurchsuchen Fenster und er will die CRT0MSG.C

    muss ich für diese Multithreading Sache noch irgendwelche LIB's einbinden? ich habe bisher nur die Process.h inkludiert



  • **Muhhuhhh

    LIBCMT.LIB
    MSVCRT.LIB

    müssen eingebunden werden, sonst kommt dieser Fehler mit dem Speicher...
    **

    Vielen Dank für eure Hilfe!!!!

    Aber noch eine Frage nebenbei..

    unsigned __stdcall WnSckConnect(void* pVoid)
    {
    	m_socket=accept(m_socket_accept,NULL,NULL);
    	Init()();
    
    	_endthreadex(0);
    	return 0;
    }
    

    Ist der Aufruf so richtig? Also besonders das beenden des Threads



  • personenkult schrieb:

    müssen eingebunden werden, sonst kommt dieser Fehler mit dem Speicher...

    Du mußt einfach nur auf MultiThreaded umschalten. Das hat Dir RockNix bereits in seinem ersten Posting als allererstes erzählt.



  • das habe ich doch schon gemacht.. sonst hätte der compiler die Funktion _beginthread auch garnicht erkannt.


Anmelden zum Antworten