try-catch und multithreading
-
moin moin!
hätte da mal wieder ne frage: ist try catch unter win eigentlich thread safe??
ich hab da nämlich 2 threads laufen die beide verschiedene instanzen einer Socket-Klasse nutzen:ein_thread_der_was_macht->socketinstanz1
ein_thread_der_was_ganz_anderes_macht->socketinstanz2wenn nun ein_thread_der_was_macht bzw dessen socketinstanz1 eine exception wirft, fängt ein_thread_der_was_ganz_anderes_macht diese in seinem try-catch block für socketinstanz2 auf

warum?
thx schon mal

-
hm. alos das sieht dann so aus:
*** Socket (1): Constructor()...
*** Socket (1): InitWSA()...
*** Socket (2): Constructor()...
*** Socket (2): InitWSA()...
threadsocket 2: connecting...
threadsocket 1: connecting...
*** Socket (2): Connect()...
*** Socket (1): Connect()...
*** Socket (1): throwing exception at Connect()
threadsocket 2: SocketException at Socket.Connect():Ein Verbindungsversuch ist
fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht ordnun
gsgemõ▀ reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der ve
rbundene Host nicht reagiert hat. Error Code: 10060jemand vielleicht n plan woran das liegen könnte?
ich benutze dev-cpp und die threads sowie das socket sind reine winapi:
soll ich mal den source posten?? kann mir dann vielleicht jemand helfen??mfg
-
vielleicht ist das zufall weil beide sockets sich gleichzeitig connecten und beide den selben timeout-wert haben. teste doch mal indem sich einer etwas später connected ob das immer noch passiert.
-
das hab ich ja schon
der 1. thread "sleept" 1000ms der 2. 5000...
außerdem werden dann beide threads beendet, obwohl ja der 1.thread dann ja noch wenigstenes auf die exceptions des socket2 warten müßte.
-
hab das problem jetzt mal eingekreist:
Thread.h
#ifndef _THREAD_ #define _THREAD_ #include <windows.h> namespace mylib { class Thread { private: HANDLE h; bool running; unsigned int id; int stoptimeout; int killtimeout; public: /* Ctor: */ Thread(); /* Ctor: */ Thread(const unsigned int &id); /* Ctor: */ Thread(const int &s, const int &k); /* Ctor: */ Thread(const unsigned int &id, const int &s, const int &k); /* Dtor: */ virtual ~Thread(); /* Thread starten. (User) */ virtual void Start(); /* Thread beenden. (User) */ virtual void Stop(); /* Hier drin alles... */ virtual unsigned int Run(); /* Thread weich stoppen lassen. */ virtual void SetRunning(const bool &r); /* Läuft der Thread? */ virtual bool IsRunning() const; virtual int GetId() const; virtual void SetStopTimeout(const int &t); virtual void SetKillTimeout(const int &t); virtual const int &GetStopTimeout() const; virtual const int &GetKillTimeout() const; private: /* Thread killen. */ virtual void Kill(); /* Instanz erzeugen */ static unsigned _stdcall StartThread(void*); }; } #endif // _THREAD_Thread.cpp
#include "Thread.h" #include <process.h> using namespace mylib; /****************************** public: ******************************/ Thread::Thread() { running=false; id=0; stoptimeout=2000; killtimeout=2000; } Thread::Thread(const unsigned int &id) { running=false; this->id=id; stoptimeout=2000; killtimeout=2000; } Thread::Thread(const int &s, const int &k) { running=false; stoptimeout=s; killtimeout=k; } Thread::Thread(const unsigned int &id, const int &s, const int &k) { running=false; this->id=id; stoptimeout=s; killtimeout=k; } Thread::~Thread() { if (running) Kill(); // Thread muß beendet sein, BEVOR CloseHandle(h); } void Thread::Start() { if (running) return; running=true; // Thread erzeugen, "this" als PVOID Thread-Parameter übergeben h=(HANDLE)_beginthreadex(0,0,StartThread,this,0,0); } void Thread::Stop() /*throw(ThreadException)*/ { if (!running) return; running=false; // Warten das Thread beendet ist: if (!WaitForSingleObject(h, stoptimeout)==ERROR_SUCCESS) Kill(); CloseHandle(h); } unsigned int Thread::Run() { /* ... */ return 0; } void Thread::SetRunning(const bool &r) { running=r; } bool Thread::IsRunning() const { return running; } int Thread::GetId() const { return id; } void Thread::SetStopTimeout(const int &s) { stoptimeout=s; } void Thread::SetKillTimeout(const int &k) { killtimeout=k; } const int &Thread::GetStopTimeout() const { return stoptimeout; } const int &Thread::GetKillTimeout() const { return killtimeout; } /****************************** private: ******************************/ void Thread::Kill() { running=false; // Warten das Thread beendet ist: WaitForSingleObject(h, killtimeout); // statt dessen evtl. Wait mit timeout + TerminateThread falls nicht von allein if (!TerminateThread(h, 0)) { CloseHandle(h); } CloseHandle(h); } unsigned _stdcall Thread::StartThread(void* threadobj) { Thread *instance=static_cast<Thread*>(threadobj); return instance->Run(); }threadtest.h
#include "Thread.h" class threadtest : public mylib::Thread { public: threadtest(int &id) :Thread(id) { } ~threadtest() { printf("threadtest %d: destructing...\n",GetId()); } unsigned int Run() { try { if (GetId()==1) { printf("threadtest %d: Sleeping()...\n",GetId()); Sleep(5000); } else Sleep(10000); int i; printf("threadtest %d: throwing...\n",GetId()); throw (i); catch (const int &i) { printf("threadtest %d: Error!!\n",GetId()); } printf("threadtest %d: quiting...\n",GetId()); return 0; } };main.cpp
#include "threadtest.h" int main(int argc, char *argv[]) { int i=1; threadtest t1(i); i=2; threadtest t2(i); t1.Start(); t2.Start(); Sleep(30000); t1.Stop(); t2.Stop(); system("PAUSE"); return EXIT_SUCCESS; }dies führt dann zu der ausgabe:
threadsocket 1: Sleeping()...
threadsocket 1: throwing...
threadsocket 2: Error!!
threadsocket 2: quiting...argh!! ich raste bald aus! warum passiert das???
-
poste nicht soviel unnützen code sondern das nur wichtigste
-
wieso unnützer code?

das ist ja schon das wichtigste!
meine thread klasse will halt wohl irgendwie nicht.
ich versuchs nochmal zu reduzieren:Thread.h
#ifndef _THREAD_ #define _THREAD_ #include <windows.h> namespace mylib { class Thread { private: HANDLE h; bool running; unsigned int id; int stoptimeout; int killtimeout; public: /* Ctor: */ Thread(); /* Ctor: */ Thread(const unsigned int &id); /* Dtor: */ virtual ~Thread(); /* Thread starten. */ virtual void Start(); /* Thread beenden. */ virtual void Stop(); /* Hier drin alles... */ virtual unsigned int Run(); /* Thread weich stoppen lassen. */ virtual void SetRunning(const bool &r); /* Läuft der Thread? */ virtual bool IsRunning() const; virtual int GetId() const; private: /* Thread killen. */ virtual void Kill(); /* Instanz erzeugen */ static unsigned _stdcall StartThread(void*); }; } #endif // _THREAD_Thread.cpp
#include "Thread.h" #include <process.h> using namespace mylib; /****************************** public: ******************************/ Thread::Thread() { running=false; id=0; stoptimeout=2000; killtimeout=2000; } Thread::Thread(const unsigned int &id) { running=false; this->id=id; stoptimeout=2000; killtimeout=2000; } Thread::~Thread() { if (running) Kill(); // Thread muß beendet sein, BEVOR CloseHandle(h); } void Thread::Start() { if (running) return; running=true; // Thread erzeugen, "this" als PVOID Thread-Parameter übergeben h=(HANDLE)_beginthreadex(0,0,StartThread,this,0,0); } void Thread::Stop() { if (!running) return; running=false; // Warten das Thread beendet ist: if (!WaitForSingleObject(h, stoptimeout)==ERROR_SUCCESS) Kill(); CloseHandle(h); } unsigned int Thread::Run() { /* ... */ return 0; } void Thread::SetRunning(const bool &r) { running=r; } bool Thread::IsRunning() const { return running; } int Thread::GetId() const { return id; } /****************************** private: ******************************/ void Thread::Kill() { running=false; // Warten das Thread beendet ist: WaitForSingleObject(h, killtimeout); if (!TerminateThread(h, 0)) { CloseHandle(h); } CloseHandle(h); } unsigned _stdcall Thread::StartThread(void* threadobj) { Thread *instance=static_cast<Thread*>(threadobj); return instance->Run(); }so das ist jetzt minimaler. dachte ich poste ein kompilierbares vollständiges beispiel, damit man denn fehler besser sieht.

bitte hilf mir jemand!!
-
falls es jemanden interessiert:
der fehler liegt wohl an dev-cpp bzw dessen library. mit visual c++ läuft der selbe source ohne probleme...
werde jetzt mal gucken was sich da machen läßt
-
Boost-Threads?
-
FireFlow schrieb:
Boost-Threads?
ja hab ich auch schon überlegt. die boost-lib ist ja auch portabel oder? und muß auf dem zielsystem nicht zwingend installiert sein oder?
-
sn0b schrieb:
FireFlow schrieb:
Boost-Threads?
ja hab ich auch schon überlegt. die boost-lib ist ja auch portabel oder? und muß auf dem zielsystem nicht zwingend installiert sein oder?
Wenn du es statisch dazulinkst nicht. Die Boost-Threads laufen jedenfalls auf Linux und Windows mehr kann ich nicht sagen.
-
löl. ich habs jetzt gefunden. (ganz ohne euch :p )
zum compiler aufruf muß -mthreads hinzugefügt werden.
komischerweise lief multithreading ohne exceptions auch ohne diesen parameter ohne probleme...
naja jetzt läuft auch das

an alle trotzdem thx fürs lesen

cu