Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Einen Thread erneut verwenden!

Empfohlene Antworten

Veröffentlicht

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);

	}

}

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.

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...!

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.

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?

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.

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?

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.