Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: WinAPI ::  Einen Thread erneut verwenden!     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
paddy_de
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.03.2010
Beiträge: 6
Beitrag paddy_de Mitglied 18:12:21 08.03.2010   Titel:   Einen Thread erneut verwenden!            Zitieren

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 ein bißchen Quellcode, falls noch andere Teile oder alles benötigt wird einfach bescheid sagen!

struct vom Threadpool:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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;
    }
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
    }
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
}
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
    }
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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);
    }
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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);
}
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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);
    }
}
FrEEzE2046
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.12.2008
Beiträge: 786
Beitrag FrEEzE2046 Mitglied 18:35:45 08.03.2010   Titel:              Zitieren

Ohne viel gelesen zu haben:
Falsche herangehensweiße. SuspendThread ist gedacht für Debugger.
C++ Forumbot
Forumbot

Benutzerprofil
Anmeldungsdatum: 29.02.2004
Beiträge: 16158
Beitrag C++ Forumbot Forumbot 19:06:20 08.03.2010   Titel:              Zitieren

Dieser Thread wurde von Moderator/in rüdiger aus dem Forum ANSI C in das Forum WinAPI verschoben.

Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?


Dieses Posting wurde automatisch erzeugt.

_________________
Besuchen Sie unsere Bücherecke.
http://www.c-plusplus.de/bucher.php
Mit jeder Bestellung unterstützen Sie das Forum.
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13513
Beitrag Martin Richter Moderator 12:10:13 09.03.2010   Titel:              Zitieren

http://blog.kalmbachnet.de/?postid=6
http://blog.kalmbachnet.de/?postid=16

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
paddy_de
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.03.2010
Beiträge: 6
Beitrag paddy_de Mitglied 13:51:07 10.03.2010   Titel:              Zitieren

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?
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13513
Beitrag Martin Richter Moderator 14:07:22 10.03.2010   Titel:              Zitieren

Nimm doch ein Event für jeden Thread, das signalisiert, dass neue Arbeit vorhanden ist.

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
paddy_de
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.03.2010
Beiträge: 6
Beitrag paddy_de Mitglied 18:21:57 10.03.2010   Titel:              Zitieren

ok das hört sich interessant an! kannst du mir vielleicht auch ein bißchen beschreiben, wie ich das genau machen kann? msdn hilft mir dabei irgendwie nicht so wirklich weiter..was aber auch daran liegen könnte, dass ich noch ziemlicher anfänger bin! ;) Ausbildung läuft erst ein 3/4 jahr!

danke für die reichlichen antworten!

Für konkrete Beispiele bin ich immer empfangsbereit! :D
tobZel
Mitglied

Benutzerprofil
Anmeldungsdatum: 17.04.2006
Beiträge: 281
Beitrag tobZel Mitglied 17:54:07 11.03.2010   Titel:              Zitieren

guck nach
CreateEvent //machst en event am besten für jeden deiner threads einen
SetEvent //setzt ein event im main thread
WaitForSingleObject //lässt deinen thread warten bis das event mit SetEvent gesetzt wurde

Is ganz einfach guck mal danach inner msdn sind genug beispiele
C/C++ Forum :: WinAPI ::  Einen Thread erneut verwenden!   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.