Zum Inhalt springen

Einen Thread erneut verwenden!


paddy_de

Empfohlene Beiträge

Ich hab ein Problem und zwar sitze ich gerade daran einen HTTP Server in "C" zu programmieren und da stellt sich natürlich früher oder später die aufgabe des Multithreadings mit Hilfe eines Threadpools. Genau an diesem Punkt bin ich nun auch angekommen und es stellt sich folgendes Problem:

Die 10 Threads erstelle ich am Anfang als CREATE_SUSPEND und beim ersten aufruf für jeden der zehn Threads aktiviere ich diesen mit ResumeThread und schläfer ihn am Ende wieder mit SuspendThread ein. Das Problem ist nun jedoch, wenn jeder der zehn Threads einmal etwas zu tun hatte und somit schonmal durch ResumeThread aktiviert und durch SuspendThread wieder schlafen gelegt wurde, bleibt mein Server hengen und reagiert nicht mehr! Ich kann also einen Thread nicht mehrmals verwenden.

Meine idee ist, dass ich einen Threadpool habe, den ich mit hilfe einer struktur aufbaue(linked list) und halt immer den ersten Thread benutze und ihn dann aus der linked list herausnehme! Wenn keine Threads mehr vorhanden sind, weil alle gerade verwendet werden, wird 30 sec gewartet.

ich hoffe es kann mir jemand weiterhelfen, bin schon ziemlich am verzweifeln!

Danke schonmal!

Hier noch ein bissl Sourcecode:

struct vom Threadpool:


typedef struct THREADPOOL_s

{

	LPDWORD wThreadID;

	CRITICAL_SECTION csectionAccept;

	HANDLE hThread;


	SOCKET sdAccept;

	fd_set rfds;

	bool bStopRunning;


	MYSQL *pMySQL; //!


	THREADPOOL_s *pThreadNext;

}

THREADPOOL_t;

init ThreadPool:

pStart_T = (THREADPOOL_t*) malloc(sizeof(THREADPOOL_t));


	if (pStart_T == NULL)

		return -1;


	memset(pStart_T, 0, sizeof(THREADPOOL_t));


	pStart_T->hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pfnThreadMessage, pStart_T, CREATE_SUSPENDED, pStart_T->wThreadID);


	if (pStart_T->hThread == NULL)

	{

		printf("errorcode: %d\n", GetLastError());

		cleanup(pStart_M, NULL);

		free(pStart_T);

		printf("Cannot create Thread!\n");

		return -1;

	}


	pTmp_T = pStart_T;


	for (i = 0; i < 10; i++)

	{


		pNew_T = (THREADPOOL_t *)malloc(sizeof(THREADPOOL_t));


		if (pNew_T == NULL)

		{

			cleanup(pStart_M, pStart_T);

			return -1;

		}


		memset(pNew_T, 0, sizeof(THREADPOOL_t));


		pNew_T->hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pfnThreadMessage, pNew_T, CREATE_SUSPENDED, pNew_T->wThreadID);


		if (pNew_T->hThread == NULL)

		{

			cleanup(pNew_M, pNew_T);

			printf("Cannot create Thread!\n");

			return -1;

		}


		pTmp_T->pThreadNext = pNew_T;

		pTmp_T = pNew_T;

	}

benutzen des Threads:

do

	{

		if (listen(sdListen, MAX_SERVER_CONNECTIONS) == -1)

		{

			printf("Error listen()\r\n");

			continue;

		}


		pThread = allocThreads();


		if (pThread->hThread == NULL)

		{

			//deleteMessage(pThread);

			free(pThread);

			printf("No Threads are available!\n");

		}

		else

		{

			pThread->sdAccept = accept(sdListen, NULL, NULL);


			if (pThread->sdAccept == -1)

			{

				releaseThread(pThread);

				printf("connection failed! socket\r\n");

				continue;

			}


			dwRet = ResumeThread(pThread->hThread);


			if (dwRet == -1)

			{

				printf("errorcode: %d\n", GetLastError());

				//deleteMessage(pThread);

				free(pThread);

				printf("Cannot resume Thread!\n");

				releaseThread(pThread);

			}

		}

}

	while (1);

alloc thread funktion:

static THREADPOOL_t* allocThreads()

{

	THREADPOOL_t *pActive, *pTMP;


	mutexlock(true);

	pTMP = pFirst_T;


	if (pTMP != NULL)

	{

		pActive = pTMP;

		pFirst_T = pTMP->pThreadNext;


		mutexlock(false);


		return pActive;

	}

	else

	{

		mutexlock(false);

		return NULL;

	}

}

thread hat seine aufgabe erledigt:

if (recvCommand(pThread) == 0)

	{

		iMySQLControl = 0;


		if (shutdown(pThread->sdAccept, 0) != 0)

			printf("shutdown-error(M)!\r\n");


		closesocket(pThread->sdAccept);

		killmutex(pThread);

		//deleteMessage(pThread);

		//free(pThread);

		printf("Connection: closed\r\n\r\n\r\n");

		releaseThread(pThread);


		return (void *) -1;

	}

zu guter letzt die release Thread Funktion:

void releaseThread(THREADPOOL_t *pThread)

{

	THREADPOOL_t *pTMP;

	DWORD dwRet;


	mutexlock(true);


	if (pFirst_T != NULL)

	{

		pTMP = pFirst_T;


		while (pTMP->pThreadNext != NULL)

			pTMP = pTMP->pThreadNext;


		pTMP->pThreadNext = pThread;

		pTMP->pThreadNext->pThreadNext = NULL;

	}

	else

	{

		pFirst_T = pThread;

		pFirst_T->pThreadNext = NULL;

	}


	mutexlock(false);

	dwRet = SuspendThread(pThread->hThread);


	if (dwRet == -1)

	{

		printf("errorcode: %d\n", GetLastError());

		exit(0);

	}

}

Link zu diesem Kommentar
Auf anderen Seiten teilen

Die 10 Threads erstelle ich am Anfang als CREATE_SUSPEND und beim ersten aufruf für jeden der zehn Threads aktiviere ich diesen mit ResumeThread und schläfer ihn am Ende wieder mit SuspendThread ein.
Das ist eine ganz schlechte Idee. Siehe die Hinweise in der MSDN Library zu SuspendThread.

Diese Funktionen sind eigentlich nur für Debugger gedacht. Wenn du einen Thread in dem Moment schlafen legst, wenn er gerade ein Lock auf eine Ressource des Betriebssystems hat, kann dein ganzes Programm hängenbleiben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das ist eine ganz schlechte Idee. Siehe die Hinweise in der MSDN Library zu SuspendThread.

Diese Funktionen sind eigentlich nur für Debugger gedacht. Wenn du einen Thread in dem Moment schlafen legst, wenn er gerade ein Lock auf eine Ressource des Betriebssystems hat, kann dein ganzes Programm hängenbleiben.

Das hab ich gelesen ja und ich weiß auch, dass das nicht zu empfehlen ist es so zu machen. Mein chef möchte das aber gerne und daher suche ich nach einer lösung das trotzdem so zu machen. ;) nur so langsam bin ich am verzweifeln, da ich keine geeignete lösung finde...!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das hab ich gelesen ja und ich weiß auch, dass das nicht zu empfehlen ist es so zu machen.

Es ist nicht "nicht zu empfehlen". Es ist für das, was du vorhast, komplett ungeeignet.

Why you should never call Suspend/TerminateThread (Part I) - Jochen Kalmbach's WebLog

Why you should never call Suspend/TerminateThread (Part II) - Jochen Kalmbach's WebLog

Mein chef möchte das aber gerne und daher suche ich nach einer lösung das trotzdem so zu machen.
Dann wirst du deinem Chef klarmachen müssen, dass das so nicht geht.
Link zu diesem Kommentar
Auf anderen Seiten teilen

ok...dann werde ich das wohl anders machen müssen. gibt es denn eine möglichkeit das grundprinzip umzusetzen, dass ich beim start des servers die 10 threads erstelle und sie dann nachher immer verwende und wieder weglege(pausieren, oder was auch immer), halt nur nicht mit suspend thread dann?

Link zu diesem Kommentar
Auf anderen Seiten teilen

gibt es denn eine möglichkeit das grundprinzip umzusetzen, dass ich beim start des servers die 10 threads erstelle und sie dann nachher immer verwende und wieder weglege(pausieren, oder was auch immer), halt nur nicht mit suspend thread dann?

Benutz die üblichen Synchronisationsobjekte: Events, Mutexe, Semaphoren oder Critical Sections, die sind für so etwas gedacht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

ok das hab ich mir schon gedacht...hab mir das auch alles schon durchgelesen, aber so wirklich weit bin ich damit noch nicht gekommen! naja aber danke auf jeden fall dür die schnelle Hilfe! ich werd mir dann wohl noch ein paar tage den kopf darüber zerbrechen!

Hat vll schonmal jemand sowas ähnliches gemacht und kann mir ein bißchen beispielcode schicken oder so?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...