Verständnissfragen zu CreateThread _beginthread



  • MSDN schrieb:

    The _beginthreadex function gives you more control over how the thread is created than _beginthread does. The _endthreadex function is also more flexible. For example, with _beginthreadex, you can use security information, set the initial state of the thread (running or suspended), and get the thread identifier of the newly created thread. You are also able to use the thread handle returned by _beginthreadex with the synchronization APIs, which you cannot do with _beginthread.



  • _beginthread(threadFunc, 0, (void 😉 i);

    Stimmt, wer lesen kann is klar im Vorteil!!!
    Man sollte schon an der richtigen Stelle den Parameter übergeben 🙄

    Danke! Is wohl doch schon zu spät!
    Was sagst du zu dem Handle? Irgendwie scheint's zu gehn.

    Gruß Threaddy!



  • BTW, Du solltest im übrigen die Handles alle wieder schließen nach Benutzung...

    CloseHandle[i];
    

    Und es ist egal, was ich zu den Handles sage, entscheident ist die MSDN, und die hab ich oben bereits zitiert...



  • Ok,

    dann woll'n wer uns mal nicht über die MSDN hinwegsetzten, mal schaun ob's dann irgendwie anders aussieht. War jetzt nur neugierig (wenn kein Handle zurückkommt müsst die Ausgabe doch anders aussehen) 😕

    Gruß und Schönen Abend noch
    Threaddy



  • Sicherlich liefert _beginthread einen Wert zurück, ohne Frage.

    Du kannst diesen Handle aber nicht mit den Funktionen aus der Syncronisations-API benutzen...

    Werte doch mal den Rückgabewert von WaitForSingleObject aus...

    MSDN schrieb:

    If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following values.

    Return code Description
    WAIT_ABANDONED
    The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.

    WAIT_OBJECT_0
    The state of the specified object is signaled.

    WAIT_TIMEOUT
    The time-out interval elapsed, and the object's state is nonsignaled.

    If the function fails, the return value is WAIT_FAILED. To get extended error information, call GetLastError.



  • [EDIT] käse 🤡 [/EDIT]



  • Hinterlass hier bitte nicht deine Füße. 😉



  • Hi,

    CloseHandle[i];

    OkOk 'Invalid Handle' bei 'CloseHandle(mythread[i])' (wohl ehr so) überzeugt mich dann doch! Wollte ja keinem widersprechen, wollt's halt nur wissen (bin neugierig).
    Das ganze sieht jetzt so aus:

    unsigned __stdcall threadFunc(void* nr);
    
    void main()
    {
    	HANDLE mythread[5];
    	for (int i=0; i<5; i++)
    	{
    		//mythread[i]=CreateThread(NULL,256,(LPTHREAD_START_ROUTINE)threadFunc,(void*)i,NULL,NULL);
    		mythread[i]=NULL;
    		mythread[i]=(HANDLE)_beginthreadex(NULL,0,&threadFunc,(void*)i,0,NULL); 
    		printf("Handle[%i]=%d\n",i,mythread[i]);
    	}//
    	printf("\n");
    	while(!kbhit()) //beendet die Schleife sobald eine Taste gedrückt wird
    	{
    		printf("Thread main\n");
    		Sleep(700);
    	}
    	printf("*** Thread main beendet ***\n");
    	for (i=0; i<5; i++)
    	{	WaitForSingleObject(mythread[i], INFINITE);
    		CloseHandle(mythread[i]);
    	}
    	printf("*** Programm beendet ***\n");
    	Sleep(5000);
    }
    
    unsigned __stdcall threadFunc(void* value)
    {
    	int nr=(int) value; //Cast des beliebigen Typs auf int
    	for (int i=0; i<20; i++)
    	{
    		printf("Thread %i\tDurchlauf: %i\n",nr,i+1);
    		Sleep(1000+(nr*100)); //Damit alles etwas realistischer wird
    	}
    	printf("*** Thread %i beendet ***\n",nr);
    	return 0;
    }
    

    hab mir den Rückgabetyp (unsigned __stdcall) aus der MSDN geklaut. Wenn jemand noch Zeit (und Geduld) hat kann er ja noch mal schreiben ob das jetzt der Calling Convention entspricht.
    Danke auf jeden Fall schon mal an alle, hat mich schon mal weiter gebracht.
    Mach jetzt erst mal Feierabend (denk mir das morgen noch mal durch).

    Gruß Threaddy



  • Jo paßt.

    Wenn Dir die ganze casterei zuviel wird, in dem Buch "Microsoft Windows Programmierung für Experten" (Link siehe oben von CMatt gepostet) bekommt man ein Makro, welches die Casterei übernimmt.

    typedef unsigned(__stdcall *PTHREAD_START) (void *);
    
    #define MyBeginThreadEx(psa, cbStack, pfnStartAddr, pvParam, fdwCreate, pdwThreadId) \
    	((HANDLE)_beginthreadex((void *)(psa),(unsigned)(cbStack),(PTHREAD_START)(pfnStartAddr),(void *)(pvParam),(unsigned)(fdwCreate),(unsigned *)(pdwThreadId)))
    

    So startest Du dann einen Thread:

    hThreadHandle = MyBeginThreadEx(NULL, 0, Thread_Funktion, Parameter, NULL, NULL);
    

    Die Deklaration der ThreadFunktion sieht dann so aus:

    DWORD WINAPI Thread_Funktion(void *Parameter);
    

    Somit brauchst Du Dir dann um das casten keinen Kopp mehr machen...



  • Moin,

    vielen dank noch mal an euch alle, habt mir echt weitergeholfen!!!
    Das mit dem Makro klingt nicht schlecht (werd ich auf jeden fall mal austesten).
    Denk daß ich jetzt im groben durchblicke. Werde jetzt noch etwas mit den Casts und Calling Conventions herumspielen (nur verständnisshalber).
    ⚠ Nochmals Danke, und schönen Tag. ⚠

    Gruß Threaddy



  • Hi,

    hätte da noch eine Frage:
    Wie kann ich feststellen ob ein Thread noch läuft (nicht darauf warten wie mit WaitForSingleObject)?

    Danke im Voraus!

    Gruß Threaddy



  • if(WaitForSingleObject(hThread,0)==WAIT_TIMEOUT)
    { 
       // Thread läuft noch
    }
    else
    {
       // Thread läuft nimmer
    }
    


  • Hi,
    steht ja auch so (ähnlich) in der MSDN: "If dwMilliseconds is zero, the function tests the object's state and returns immediately". Schande über mich, hab so intensiv nach 'ne extra Funktion gesucht, daß ich die die ich schon kannte mir gar nicht mehr genauer angeschaut hab.
    Ich danke die für deine schnelle (und wie immer kompetente) Hilfe!

    Gruß Threaddy
    PS. Wollte eigentlich gestern gleich noch Antworten, allerdings ging da nix (Netztechnisch).


Anmelden zum Antworten