watchdog



  • Entschuldigung für den Schreibfehler im Code, ich habe ihn korrigiert.

    @ King Ohne die prügelen zu wollen, will soll man sonst in C multithreaded programmieren?
    Ich brauche dazu eine Funktion des Betriebssystems, welche mir einen Thread startet.



  • PAD schrieb:

    @ King Ohne die prügelen zu wollen, will soll man sonst in C multithreaded programmieren?

    Jedenfalls nie mit _beginthread. Das Problem ist, daß Dich diese Funktion über die Geschehnisse im Unklaren lässt. Der Rückgabewert ist zwar das Thread-Handle, aber leider ist es nicht gültig (wird intern geschlossen). Verwendest Du stattdessen _beginthreadex, bekommst Du ein gültiges Handle geliefert. Damit kannst Du auch Deine Synchronisations-Probleme auf einen Schlag lösen. Allerdings mußt Du nun das Handle selbst schliessen. Das ist aber nun wirklich kein Problem. Ach ja, die Thread-Funktion hat auch eine andere Signatur. Du kannst jetzt sogar einen Wert zurückgeben!

    UINT WINAPI DoSomething(void* pv)  
    {  
    Sleep(2000); 
    
    pPad[0]=300; 
    
    return(0);
    }  
    
    int* pPad; 
    
    int main()  
    {  
     HANDLE hThread;
     DWORD  dwCode;
    
     if (0==(pPad = malloc(128))) 
      { 
       printf("\nmalloc failed\n); 
       return -1 
      } 
    
      hThread = (HANDLE)_beginthreadex(DoSomething(pVoid));  
      WaitForSingleObject(hThread, INFINITE);
      free(pPad);  // hier kommst du an, wenn der Thread beendet ist
    
      if(WillHabenRückgabe)
          GetExitCodeThread(hThread, &dwCode);
    
      CloseHandle(hThread); // Thread-Handle zu Fuss schliessen
    
      return 0;  
    }
    

    Ich brauche dazu eine Funktion des Betriebssystems, welche mir einen Thread startet.

    Du sprichst von CreateThread? Das geht natürlich auch, nur mußt Du hier ganz genau wissen, was Du tust. Du übergehst damit die CRT. Solange Du im Thread nur API-Funktionen aufrufst, ist das auch kein Problem. Kommt eine Funktion aus der CRT ins Spiel, wird das schnell zum Abenteuer.

    Schau Dir die allseits beliebte Funktion strtok an. Diese speichert Ihren Zustand bis zum nächsten Aufruf (der z.B. mit NULL im ersten Parameter erfolgen kann). Stell Dir jetzt zwei Threads vor, die gleichzeitig strtok verwenden möchten.

    Probleme machen auch alle die Funktionen, die Fehler melden. Der VC löst das beispielsweise über errno. Aber welchen Fehler hält die Variable? Zu welcher Funktion aus welchem Thread gehört das?

    Wenn Du aber die CRT Funktion _beginthread/ ex verwendest, gibt es all diese Probleme nicht. Über die interne Initialisierung ist es möglich, daß jeder Thread seinen eigenen Zustand halten kann.



  • @-King- Danke für die Information über die Probleme von _beginthread.

    Mit dem Überlappen habe ich keine Probleme, ich wollte nur zu deinem Beispiel des nicht erreichbaren free´s noch ein anderes typisches Problem von multithreading zeigen.

    Die Lösung vor dem Verlassen des Hauptprogramms auf alle threads zu warten, kann auch nicht das Designproblem beheben das der thread einer inzwischen freigegebenen Variablen einen Wert zuweist.

    Eigentlich war deine Antwort mit _beginthreadex schon ausreichend, denn wenn du _beginthread ablehnst (mit sinnvollen Gründen) braucht man eine Alternative dazu, das diese schon durch _beginthreadex gegeben ist, war aus deinem Text nicht ersichtlich.



  • hab die folgenden header includiert

    #include <windows.h>
    #include <process.h>
    #include <iostream.h>

    und er mag das einfach ned machen:

    itsThreadHandle = (HANDLE) _beginthreadex(inputfunktion());

    und spuckt das aus:

    Borland C++ 5.6 für Win32 Copyright (c) 1993, 2002 Borland
    threads.cpp:
    Fehler E2268 threads.cpp 24: Aufruf der undefinierten Funktion '_beginthreadex'
    in Funktion MyThread::startThread()
    *** 1 Fehler bei der Compilierung ***

    was bringt das UINT WINAPI vor DoSomething(void* pv) eigentlich?
    was hat beginthreadex noch so für parameter (MSDN bringst mir nix)?

    Gruß TheChosn



  • TheChosn schrieb:

    Borland C++ 5.6 für Win32 Copyright (c) 1993, 2002 Borland
    threads.cpp:
    Fehler E2268 threads.cpp 24: Aufruf der undefinierten Funktion '_beginthreadex'
    in Funktion MyThread::startThread()
    *** 1 Fehler bei der Compilierung ***

    Ich könnte mir vorstellen, dass die Funktion im BCB anders heißt 🙄

    TheChosn schrieb:

    was bringt das UINT WINAPI vor DoSomething(void* pv) eigentlich?

    afaik ist UINT der Rückgabetyp und WINAPI (define aus windef.h) die Aufrufkonvention ( __cdecl )

    TheChosn schrieb:

    was hat beginthreadex noch so für parameter (MSDN bringst mir nix)?

    Wie hast du denn gesucht? http://msdn.microsoft.com/library/en-us/vccore98/html/_crt__beginthread.2c_._beginthreadex.asp



  • Hmm konnte nix finden was borland spezifisch wäre, das is in der header datei von borland.

    unsigned long _RTLENTRY _EXPFUNC _beginthreadex(void *__security_attr,
    unsigned __stksize,
    unsigned (__stdcall *__start)(void *),
    void *__arg,
    unsigned __create_flags,
    unsigned *__thread_id);

    Kannst du mir bitte noch kurz erklären was es mit den calling conventions auf sich hat?

    The routine at start_address must use the __cdecl calling convention and should have no return value.

    Wie finde ich die adresse einer Funktion raus, mag sie im konstruktor übergeben gehört ned der klasse.

    Gruß TheChosn



  • das mit den calling conventions bestimmt afaik, in welcher Reihenfolge die Parameter an die Funktion übergeben werden (von rechts nach links, oder umgekehrt) 🙄

    Du musst immho einfach den Namen übergeben (so wie z.B. bei Fensterklassen - WndProc)



  • Hast du dem Borland Compiler auch mitgeteilt, das du multithreaded arbeiten willst. Ich kann mich erinnern das wir eine ähnliche Fehlermeldung hatten als wir einmal unter MSVC 6.0 als wir in einer als singlethreraded definierten Applikation einen thread aufmachen wollten.



  • Wie kann ich meinem Borland Compiler denn das mitteilen?
    Bin leider ziemlicher Anfänger 😕

    Gruß TheChosn



  • flenders schrieb:

    afaik ist UINT der Rückgabetyp und WINAPI (define aus windef.h) die Aufrufkonvention ( __cdecl )

    WINAPI ist __stdcall.

    flenders schrieb:

    das mit den calling conventions bestimmt afaik, in welcher Reihenfolge die Parameter an die Funktion übergeben werden (von rechts nach links, oder umgekehrt)

    Das ist richtig, aber nur die halbe Wahrheit. Zusätzlich wird festgelegt, wer den Stack aufräumt (die Funktion oder der Aufrufer).



  • Was ist jetz eigentlich der unterschied zwischen den beiden
    außer Security, Init & Adressflag?
    Liefern die nicht beide ein handle?

    _beginthread
    _beginthreadex

    Hab immer noch keinen Erfolg mit der Compilierung, hat es sinn sich im Cbuilder Forum umzuhören oder verwendet niemand mehr den ollen commadozeilen compiler?



  • <a href= schrieb:

    http://msdn.microsoft.com/library/en-us/vccore98/html/_crt__beginthread.2c_._beginthreadex.asp">_beginthreadex resembles the Win32 CreateThread API more closely than does _beginthread. _beginthreadex differs from _beginthread in the following ways:

    • _beginthreadex has three additional parameters: initflag, security, threadaddr. The new thread can be created in a suspended state, with a specified security (Windows NT only), and can be accessed using thrdaddr, which is the thread identifier.
    • The routine at start_address passed to _beginthreadex must use the __stdcall calling convention and must return a thread exit code.
    • _beginthreadex returns 0 on failure, rather than 1.
    • A thread created with _beginthreadex is terminated by a call to _endthreadex.


  • Wie sieht dein Code jetzt eigentlich aus? Falls du Probleme mit deinem Compiler hast findest du sicher im BCB (oder andere Compiler?) Forum jemanden, der dir helfen kann 😉



  • TheChosn schrieb:

    Liefern die nicht beide ein handle?

    Ja, liefern sie. Das HANDLE von _beginthread ist aber leider schon geschlossen. Damit kannst Du weiter nichts beschicken. Du kannst lediglich feststellen, ob der Aufruf geklappt hat oder nicht.



  • Tja also mit
    DevC++ wenn das jemand kennt geht jetz die variante ohne ex,
    hatte wohl paar argumente falsch übergeben.
    Mit Borland gehts bis dato noch nicht.

    Bei der Variante mit ex häng ich wieder, was kann ich 0-setzen was nicht?

    _beginthreadex( 0,0,Bounce, 0, &ch,0,&itsThreadId);

    Gruß TheChosn



  • Also laut doku, hat das nur 6 Parameter 🙄 und da steht auch, was du jeweils einsetzen darfst



  • Juhuu es funktioniert endlich,
    hat jemand ne Compilerempfehlung für mich?
    Der Borland war sehr gut aber ich bin zu blöd um ihn zum Multithreading zu bewegen. Der Dev-C hat Fehlermeldungen mit denen ich nix anfangen kann,
    mit der C Builder Trial schaff ich es ums verrecken nicht ein Konsolenproject
    zu entwickeln sonst is er mein liebling was die fehlersuche angeht...
    Tja ich hab Probleme 😃

    Danke für eure Hilfe



  • Beim Borland Compiler gibt's nen Parameter -tWM für Multithreading. Zumindest beim
    5.5.



  • Hättest du das mal zwei Monate früher geschrieben, dann wäre es immer noch ein Jahr zu spät 😉


Anmelden zum Antworten