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 nach bestimmter Zeit unterbrechen     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
curry-king
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.07.2004
Beiträge: 984
Beitrag curry-king Mitglied 12:43:21 02.02.2012   Titel:   Einen Thread nach bestimmter Zeit unterbrechen            Zitieren

Hallo zusammen,

wie erreiche ich es, daß ein Thread (CreateThread...) nach x Sekunden sich unterbricht bzw. in den signalled state wecheselt?

Danke!

_________________
Ich habe aus dieser sogenannten höchsten Erleuchtung nichts gewonnen, und genau aus diesem Grund heißt sie auch höchste Erleuchtung - Gautama Buddha
dot
Mitglied

Benutzerprofil
Anmeldungsdatum: 20.05.2004
Beiträge: 3858
Beitrag dot Mitglied 12:44:46 02.02.2012   Titel:              Zitieren

Indem du dafür sorgst dass die ThreadProc nach x Sekunden returned...

_________________
one point of view will never reveal the entire scene.
curry-king
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.07.2004
Beiträge: 984
Beitrag curry-king Mitglied 13:20:20 02.02.2012   Titel:              Zitieren

Das Problem ist wenn sich das Thread_proc nach x sec beendet und 50 Threads laufen, die Kontextwechsel der Threads die Zeit verfälschen. Ich möchte meine Threads aber nach x Sekunden "Threadlaufzeit" beenden.

Welche Funktionen helfen da?

_________________
Ich habe aus dieser sogenannten höchsten Erleuchtung nichts gewonnen, und genau aus diesem Grund heißt sie auch höchste Erleuchtung - Gautama Buddha
dot
Mitglied

Benutzerprofil
Anmeldungsdatum: 20.05.2004
Beiträge: 3858
Beitrag dot Mitglied 13:25:06 02.02.2012   Titel:              Zitieren

Was genau hast du denn vor dass die Kontextwechsel zu einem Problem werden?
Bist du dir sicher dass Windows das geeignete Betriebssystem für deine Anwendung ist? Klingt mir irgendwie fast als solltest du besser ein Echtzeitbetriebssystem verwenden. Bedenke: Auch wenn du die Zeit richtig messen könntest (wofür mir momentan kein Weg einfällt), dann garantiert dir noch immer niemand dass deine Threads auch rechtzeitig drankommen um tatsächlich nach der exakten Zeitspanne zu beenden...

Vielleicht hilft dir das: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684943.aspx

Da du vom signaled state sprichst: Könntest du nicht vielleicht einfach das Timeout von WaitForSingleObject() benutzen?

_________________
one point of view will never reveal the entire scene.


Zuletzt bearbeitet von dot am 13:28:15 02.02.2012, insgesamt 3-mal bearbeitet
curry-king
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.07.2004
Beiträge: 984
Beitrag curry-king Mitglied 14:21:04 02.02.2012   Titel:              Zitieren

Ich habe 50 threads von denen jeder sagen wir netto 20 sekunden rechnen darf.
Bisher habe ich im thread
C/C++ Code:
s = clock();
// ... work
e = clock()-s;
C/C++ Code:
s = clock();
// ... work
e = clock()-s;
C/C++ Code:
s = clock();
// ... work
e = clock()-s;

sowas gemacht. Angenommen ein Kontextwechsel passiert bei thread t1. Beim erneuten wechsel zu thread t1 sind die 20 sekunden evtl. schon verstrichen obwohl der Prozessor mit anderen Threads beschäftigt war.
Ich möchte jedem Thread also netto 20 Sekunden Laufzeit geben. (Hoffentlich schreibe ich nicht totalen bullshit...).

@dot: Dein Link scheint mir hilfreich zu sein. So kann ich die Anzahl der Zyklen eines Threads auslesen. Allerdings steht dort:
Zitat:
Do not attempt to convert the CPU clock cycles returned by QueryThreadCycleTime to elapsed time.


Aber ich denke für eine Näherung wird es erstmal reichen!

_________________
Ich habe aus dieser sogenannten höchsten Erleuchtung nichts gewonnen, und genau aus diesem Grund heißt sie auch höchste Erleuchtung - Gautama Buddha
dot
Mitglied

Benutzerprofil
Anmeldungsdatum: 20.05.2004
Beiträge: 3858
Beitrag dot Mitglied 14:26:37 02.02.2012   Titel:              Zitieren

Dein Problem ist mir klar. Was ich mich frage ist: Warum genau brauchst du 50 Threads die nur exakt diese Zeit rechnen dürfen? Sicher dass es für dein eigentliches Problem nicht vielleicht eine bessere Lösung gäbe?

curry-king schrieb:
@dot: Dein Link scheint mir hilfreich zu sein. So kann ich die Anzahl der Zyklen eines Threads auslesen. Allerdings steht dort:
Zitat:
Do not attempt to convert the CPU clock cycles returned by QueryThreadCycleTime to elapsed time.


Aber ich denke für eine Näherung wird es erstmal reichen!

Ja, das Problem dabei ist eben, dass es keinen Weg gibt festzustellen auf welcher CPU dein Thread gerade läuft und wie schnell die gerade getaktet ist...

_________________
one point of view will never reveal the entire scene.


Zuletzt bearbeitet von dot am 14:27:18 02.02.2012, insgesamt 1-mal bearbeitet
curry-king
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.07.2004
Beiträge: 984
Beitrag curry-king Mitglied 14:32:11 02.02.2012   Titel:              Zitieren

Ich beschäftige mich gerade mit evolutionären Algorithmen. Meine threads entsprechen Individuen, die aus Symbolströmen Automaten lernen. Für diese Aufgabe soll ihnen nur eine bestimmte Zeit zur Verfügung stehen. Beim Überschreiten der Zeit fließt dieser Faktor mindernd in deren Fitness ein...
Ich muss also überprüfen, ob ein thread das in x Sekunden schafft oder nicht.

_________________
Ich habe aus dieser sogenannten höchsten Erleuchtung nichts gewonnen, und genau aus diesem Grund heißt sie auch höchste Erleuchtung - Gautama Buddha


Zuletzt bearbeitet von curry-king am 14:33:12 02.02.2012, insgesamt 2-mal bearbeitet
dot
Mitglied

Benutzerprofil
Anmeldungsdatum: 20.05.2004
Beiträge: 3858
Beitrag dot Mitglied 14:33:55 02.02.2012   Titel:              Zitieren

Wäre für diese Anwendung die direkte Anzahl der Taktzyklen aber nicht sowieso ein besseres Maß als die Zeit?

_________________
one point of view will never reveal the entire scene.
curry-king
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.07.2004
Beiträge: 984
Beitrag curry-king Mitglied 14:36:15 02.02.2012   Titel:              Zitieren

Stimmt! Dann werde ich mal ich mal nach einer passenden Zyklenanzahl sehen. Danke!

_________________
Ich habe aus dieser sogenannten höchsten Erleuchtung nichts gewonnen, und genau aus diesem Grund heißt sie auch höchste Erleuchtung - Gautama Buddha
dot
Mitglied

Benutzerprofil
Anmeldungsdatum: 20.05.2004
Beiträge: 3858
Beitrag dot Mitglied 14:37:07 02.02.2012   Titel:              Zitieren

Die bekommst du direkt mit der oben verlinkten Funktion ;)
QueryThreadCycleTime() sollte dir die Anzahl der Zyklen die ein Thread netto gerechnet hat liefern.

_________________
one point of view will never reveal the entire scene.


Zuletzt bearbeitet von dot am 14:37:54 02.02.2012, insgesamt 2-mal bearbeitet
curry-king
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.07.2004
Beiträge: 984
Beitrag curry-king Mitglied 14:44:11 02.02.2012   Titel:              Zitieren

Ja das war mir klar ;-). Jetzt sehe ich aber gerade, das die erst ab WinVista unterstützt wird. Ich bin hier mit XP unterwegs... mal sehen!

_________________
Ich habe aus dieser sogenannten höchsten Erleuchtung nichts gewonnen, und genau aus diesem Grund heißt sie auch höchste Erleuchtung - Gautama Buddha
curry-king
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.07.2004
Beiträge: 984
Beitrag curry-king Mitglied 14:46:23 02.02.2012   Titel:              Zitieren

GetThreadTimes() ...

_________________
Ich habe aus dieser sogenannten höchsten Erleuchtung nichts gewonnen, und genau aus diesem Grund heißt sie auch höchste Erleuchtung - Gautama Buddha
dot
Mitglied

Benutzerprofil
Anmeldungsdatum: 20.05.2004
Beiträge: 3858
Beitrag dot Mitglied 14:53:37 02.02.2012   Titel:              Zitieren

Stimmt, damit gehts auch.

_________________
one point of view will never reveal the entire scene.
zeusosc
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.12.2006
Beiträge: 745
Beitrag zeusosc Mitglied 21:33:16 03.02.2012   Titel:              Zitieren

Nimm mal lieber QueryPerformanceCounter,.. dieser gibt dir auch die Laufzeit in ns zurück,...

Hier ein beispiel:
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <time.h>
#include
<windows.h>
namespace _stde{
//##################################################################################################
//
// CPUTICKSSTRUCT
// Struct Contains informations about the Cpu ticks to calculate RunTime
//
//##################################################################################################


typedef struct _cpu_ticks_struct                // Struct Contains informations about the Cpu ticks to calculate RunTime
{
    double            dLastTime;                    //Last Time wich has been setted
    LARGE_INTEGER    liLastCount;                //Last Count number which has been setted
    double            dCheckTime;                    //Time which has been checked
    double            dReturn;                    //Return value
    LARGE_INTEGER    nFreq;                        //Frequency
    LARGE_INTEGER    nCount;                        //Tick Count
    double            GetCPUTicks(void);            //Procedure to Calulate the Framerate
    double            GetMilliseconds(void);
    _cpu_ticks_struct();                        //Ctor
    ~_cpu_ticks_struct();                        //Dtor
}CPUTICKSSTRUCT,*LPCPUTICKSSTRUCT;                //Struct Contains informations about the Cpu ticks to calculate RunTime
typedef CPUTICKSSTRUCT CTS;                        //Make it a bit shorter
typedef LPCPUTICKSSTRUCT LPCTS;                    //Make it a bit shorter
}
//##################################################################################################
//
// CPUTICKSSTRUCT
// Struct Contains informations about the Cpu ticks to calculate RunTime
//
//##################################################################################################


_stde::_cpu_ticks_struct::_cpu_ticks_struct()
{
    ZeroMemory(this,sizeof(_stde::CPUTICKSSTRUCT));
    this->dCheckTime=5.0;
};

_stde::_cpu_ticks_struct::~_cpu_ticks_struct()
{
    ZeroMemory(this,sizeof(_stde::CPUTICKSSTRUCT));
};

double _stde::_cpu_ticks_struct::GetCPUTicks()
{
    LARGE_INTEGER counter={0};

    // check for a new frequency once every 5 seconds
    // note: this is in case ACPI, etc. alters it

    if((this->nFreq.QuadPart == 0) || (this->dCheckTime < (this->dReturn)))
    {
        this->dCheckTime = this->dReturn + 5.0;

        // avoid a division by zero by returning zero on error
        if(!QueryPerformanceFrequency(&(this->nFreq))) return 0.0;
    }

    // use the ratio of tick amount divided by frequency to find the hertz
    QueryPerformanceCounter(&(this->nCount));
    if(this->liLastCount.QuadPart!=0){
        counter.QuadPart=this->nCount.QuadPart-this->liLastCount.QuadPart;
    this->dReturn = ((double)counter.QuadPart / (double)this->nFreq.QuadPart);
    };
    this->liLastCount=this->nCount;
    if(this->dReturn!=0){this->dReturn=double(1)/(this->dReturn);};
    return (this->dReturn);
};

double _stde::_cpu_ticks_struct::GetMilliseconds(void)
    { return (1000/(this->GetCPUTicks()));};

};
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <time.h>
#include
<windows.h>
namespace _stde{
//##################################################################################################
//
// CPUTICKSSTRUCT
// Struct Contains informations about the Cpu ticks to calculate RunTime
//
//##################################################################################################


typedef struct _cpu_ticks_struct // Struct Contains informations about the Cpu ticks to calculate RunTime
{
double dLastTime; //Last Time wich has been setted
LARGE_INTEGER liLastCount; //Last Count number which has been setted
double dCheckTime; //Time which has been checked
double dReturn; //Return value
LARGE_INTEGER nFreq; //Frequency
LARGE_INTEGER nCount; //Tick Count
double GetCPUTicks(void); //Procedure to Calulate the Framerate
double GetMilliseconds(void);
_cpu_ticks_struct(); //Ctor
~_cpu_ticks_struct(); //Dtor
}CPUTICKSSTRUCT,*LPCPUTICKSSTRUCT; //Struct Contains informations about the Cpu ticks to calculate RunTime
typedef CPUTICKSSTRUCT CTS; //Make it a bit shorter
typedef LPCPUTICKSSTRUCT LPCTS; //Make it a bit shorter
}
//##################################################################################################
//
// CPUTICKSSTRUCT
// Struct Contains informations about the Cpu ticks to calculate RunTime
//
//##################################################################################################


_stde::_cpu_ticks_struct::_cpu_ticks_struct()
{
ZeroMemory(this,sizeof(_stde::CPUTICKSSTRUCT));
this->dCheckTime=5.0;
};

_stde::_cpu_ticks_struct::~_cpu_ticks_struct()
{
ZeroMemory(this,sizeof(_stde::CPUTICKSSTRUCT));
};

double _stde::_cpu_ticks_struct::GetCPUTicks()
{
LARGE_INTEGER counter={0};

// check for a new frequency once every 5 seconds
// note: this is in case ACPI, etc. alters it

if((this->nFreq.QuadPart == 0) || (this->dCheckTime < (this->dReturn)))
{
this->dCheckTime = this->dReturn + 5.0;

// avoid a division by zero by returning zero on error
if(!QueryPerformanceFrequency(&(this->nFreq))) return 0.0;
}

// use the ratio of tick amount divided by frequency to find the hertz
QueryPerformanceCounter(&(this->nCount));
if(this->liLastCount.QuadPart!=0){
counter.QuadPart=this->nCount.QuadPart-this->liLastCount.QuadPart;
this->dReturn = ((double)counter.QuadPart / (double)this->nFreq.QuadPart);
};
this->liLastCount=this->nCount;
if(this->dReturn!=0){this->dReturn=double(1)/(this->dReturn);};
return (this->dReturn);
};

double _stde::_cpu_ticks_struct::GetMilliseconds(void)
{ return (1000/(this->GetCPUTicks()));};

};
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <time.h>
#include
<windows.h>
namespace _stde{
//##################################################################################################
//
// CPUTICKSSTRUCT
// Struct Contains informations about the Cpu ticks to calculate RunTime
//
//##################################################################################################


typedef struct _cpu_ticks_struct                // Struct Contains informations about the Cpu ticks to calculate RunTime
{
    double            dLastTime;                    //Last Time wich has been setted
    LARGE_INTEGER    liLastCount;                //Last Count number which has been setted
    double            dCheckTime;                    //Time which has been checked
    double            dReturn;                    //Return value
    LARGE_INTEGER    nFreq;                        //Frequency
    LARGE_INTEGER    nCount;                        //Tick Count
    double            GetCPUTicks(void);            //Procedure to Calulate the Framerate
    double            GetMilliseconds(void);
    _cpu_ticks_struct();                        //Ctor
    ~_cpu_ticks_struct();                        //Dtor
}CPUTICKSSTRUCT,*LPCPUTICKSSTRUCT;                //Struct Contains informations about the Cpu ticks to calculate RunTime
typedef CPUTICKSSTRUCT CTS;                        //Make it a bit shorter
typedef LPCPUTICKSSTRUCT LPCTS;                    //Make it a bit shorter
}
//##################################################################################################
//
// CPUTICKSSTRUCT
// Struct Contains informations about the Cpu ticks to calculate RunTime
//
//##################################################################################################


_stde::_cpu_ticks_struct::_cpu_ticks_struct()
{
    ZeroMemory(this,sizeof(_stde::CPUTICKSSTRUCT));
    this->dCheckTime=5.0;
};

_stde::_cpu_ticks_struct::~_cpu_ticks_struct()
{
    ZeroMemory(this,sizeof(_stde::CPUTICKSSTRUCT));
};

double _stde::_cpu_ticks_struct::GetCPUTicks()
{
    LARGE_INTEGER counter={0};

    // check for a new frequency once every 5 seconds
    // note: this is in case ACPI, etc. alters it

    if((this->nFreq.QuadPart == 0) || (this->dCheckTime < (this->dReturn)))
    {
        this->dCheckTime = this->dReturn + 5.0;

        // avoid a division by zero by returning zero on error
        if(!QueryPerformanceFrequency(&(this->nFreq))) return 0.0;
    }

    // use the ratio of tick amount divided by frequency to find the hertz
    QueryPerformanceCounter(&(this->nCount));
    if(this->liLastCount.QuadPart!=0){
        counter.QuadPart=this->nCount.QuadPart-this->liLastCount.QuadPart;
    this->dReturn = ((double)counter.QuadPart / (double)this->nFreq.QuadPart);
    };
    this->liLastCount=this->nCount;
    if(this->dReturn!=0){this->dReturn=double(1)/(this->dReturn);};
    return (this->dReturn);
};

double _stde::_cpu_ticks_struct::GetMilliseconds(void)
    { return (1000/(this->GetCPUTicks()));};

};


Bedenke das die Erzeugung eines Threads weitaus länger dauert (zwischen 0,5 ms bis 2,5ms, vom Aufruf CreateThread bis zum fertigen Eintritt in die THREAD_PROC) als der Kontextwechsel,...

grüße

_________________
Der Contrapart in einer Diskussion zu sein, heißt nicht das dieser Standpunkt
der eigene sein muss! ;)
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
Beitrag hustbaer Mitglied 22:47:57 03.02.2012   Titel:              Zitieren

zeusosc schrieb:
Bedenke das die Erzeugung eines Threads weitaus länger dauert (zwischen 0,5 ms bis 2,5ms, vom Aufruf CreateThread bis zum fertigen Eintritt in die THREAD_PROC) als der Kontextwechsel,...

Ich zweifle GANZ STARK daran, dass die 0.5 - 2.5 ms der Wirklichkeit entsprechen.
(Dass es länger als der Kontextwechsel dauert, damit wirst du allerdings vermutlich Recht haben - würde mich zumindest stark wundern wenn nicht)

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
zeusosc
Mitglied

Benutzerprofil
Anmeldungsdatum: 01.12.2006
Beiträge: 745
Beitrag zeusosc Mitglied 01:30:50 04.02.2012   Titel:              Zitieren

@hustbaer:

Haben wir auf zwei systemen getestet:
Aus Thread A mit Prio -15 bis 15 wird ein Thread B gestartet mit Prio -15 bis 15

Gezählt wurde die Zeit (Per QueryPerformanceCounter)
von VOR
CreateThread
Bis Nach
WaitForSingleEvent()

Der Event wurde nach Eintritt in die Threadfunk gesetzt.
Ein paar tausend Durchläufe bei Nominallast des Systems,
Die Zeit aufgetragen als DensityPlot über ThreadPrio A u B

Getestet wurden:
Core2Duo P8400 @ 2.26 Ghz 2.27 Ghz 2GBRam Max: 2250µs Min: >460µs
(ok es gab noch eine klitzekleine spitze bei Prio -15,5 bei rund 3593µs)
AMD Athlon XP 2200+ 1.80 Ghz 1.5 GBRam Max: >4040µs Min: >907µs

_________________
Der Contrapart in einer Diskussion zu sein, heißt nicht das dieser Standpunkt
der eigene sein muss! ;)
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
Beitrag hustbaer Mitglied 22:36:10 04.02.2012   Titel:              Zitieren

@zeusosc:
Kann ich nicht ganz nachvollziehen.
Ich hab jetzt keinen so ausführlichen Test mit min/max/avg gemacht und auch nur mit Priorität 0, aber da komme ich auf 110 ~ 140ms für 1000 Threads, also so 0.11 ~ 0.14ms pro Thread.
Also etwa Faktor 4 - 20 schneller als deine Zahlen.

Ganz einfacher Test, ein Thread startet immer den nächsten, der letzte setzt den Event:
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include
<Windows.h>
#include
<process.h>

#pragma
comment(lib, "winmm")

HANDLE event = 0;
size_t counter = 0;

unsigned __stdcall ThreadFn(void*);

void StartNextThread()
{
    UINT threadId = 0;
    HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &ThreadFn, 0, 0, &threadId)); // auch mit CreateThread() probiert, ändert fast nix (minimal schneller mit CreateThread())
    ::CloseHandle(thread);
}

unsigned __stdcall ThreadFn(void*)
{
    if (counter == 0)
        ::SetEvent(event);
    else
    {
        counter--;
        StartNextThread();
    }

    return 0;
}

void Run()
{
    ::ResetEvent(event);
    counter = 1000;

    StartNextThread();

    ::WaitForSingleObject(event, INFINITE);
}

int main()
{
    //::SetProcessAffinityMask(::GetCurrentProcess(), 1); // war testweise drinnen, ändert aber kaum was (minimal langsamer mit)

    event = ::CreateEventW(0, true, false, 0);

    ::timeBeginPeriod(1); // war testweise draussen, ändert aber so-gut-wie nix

    for (size_t i = 0; i < 100; i++)
    {
        ::SetThreadPriority(::GetCurrentThread(), 0);
        DWORD t0 = ::timeGetTime();
        Run();
        DWORD t1 = ::timeGetTime();
        std::cout << t1 - t0 << "\n";
    }

    ::CloseHandle(event);
}
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include
<Windows.h>
#include
<process.h>

#pragma
comment(lib, "winmm")

HANDLE event = 0;
size_t counter = 0;

unsigned __stdcall ThreadFn(void*);

void StartNextThread()
{
UINT threadId = 0;
HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &ThreadFn, 0, 0, &threadId)); // auch mit CreateThread() probiert, ändert fast nix (minimal schneller mit CreateThread())
::CloseHandle(thread);
}

unsigned __stdcall ThreadFn(void*)
{
if (counter == 0)
::SetEvent(event);
else
{
counter--;
StartNextThread();
}

return 0;
}

void Run()
{
::ResetEvent(event);
counter = 1000;

StartNextThread();

::WaitForSingleObject(event, INFINITE);
}

int main()
{
//::SetProcessAffinityMask(::GetCurrentProcess(), 1); // war testweise drinnen, ändert aber kaum was (minimal langsamer mit)

event = ::CreateEventW(0, true, false, 0);

::timeBeginPeriod(1); // war testweise draussen, ändert aber so-gut-wie nix

for (size_t i = 0; i < 100; i++)
{
::SetThreadPriority(::GetCurrentThread(), 0);
DWORD t0 = ::timeGetTime();
Run();
DWORD t1 = ::timeGetTime();
std::cout << t1 - t0 << "\n";
}

::CloseHandle(event);
}
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include
<Windows.h>
#include
<process.h>

#pragma
comment(lib, "winmm")

HANDLE event = 0;
size_t counter = 0;

unsigned __stdcall ThreadFn(void*);

void StartNextThread()
{
    UINT threadId = 0;
    HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &ThreadFn, 0, 0, &threadId)); // auch mit CreateThread() probiert, ändert fast nix (minimal schneller mit CreateThread())
    ::CloseHandle(thread);
}

unsigned __stdcall ThreadFn(void*)
{
    if (counter == 0)
        ::SetEvent(event);
    else
    {
        counter--;
        StartNextThread();
    }

    return 0;
}

void Run()
{
    ::ResetEvent(event);
    counter = 1000;

    StartNextThread();

    ::WaitForSingleObject(event, INFINITE);
}

int main()
{
    //::SetProcessAffinityMask(::GetCurrentProcess(), 1); // war testweise drinnen, ändert aber kaum was (minimal langsamer mit)

    event = ::CreateEventW(0, true, false, 0);

    ::timeBeginPeriod(1); // war testweise draussen, ändert aber so-gut-wie nix

    for (size_t i = 0; i < 100; i++)
    {
        ::SetThreadPriority(::GetCurrentThread(), 0);
        DWORD t0 = ::timeGetTime();
        Run();
        DWORD t1 = ::timeGetTime();
        std::cout << t1 - t0 << "\n";
    }

    ::CloseHandle(event);
}


System: Windows 7 64 Bit, Core2 Quad Q6600 (4 * 2.4 GHz), 8 GB RAM.

Das misst jetzt natürlich was anderes als dein Test.

Dein Test misst ja die Zeit die zum Erstellen und "Loslaufen" des neuen Threads benötigt wird + die Zeit die vom SetEvent() bis zum Aufwachen des startenden Threads vergeht.

Meiner misst nur die Zeit die zum Erstellen und "Loslaufen" des neuen Threads benötigt wird, weil der ja gleich wieder den nächsten startet, und nur zum Schluss 1x der "Eltern-Thread" aufgeweckt wird.


ps: solche Tests muss man frei laufen lassen. Wenn ich die Release Version unter Visual Studio laufen lasse, ist die mehr als Faktor 10 langsamer! Sollte klar sein, ich sag's nur vorsichtshalber trotzdem dazu.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/


Zuletzt bearbeitet von hustbaer am 22:38:59 04.02.2012, insgesamt 1-mal bearbeitet
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 13529
Beitrag hustbaer Mitglied 22:57:12 04.02.2012   Titel:              Zitieren

So, ich hab' das ganze noch schnell auf das andere Schema umgestellt:
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
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
void StartNextThread()
{
    UINT threadId = 0;
    HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &ThreadFn, 0, 0, &threadId));
    ::CloseHandle(thread);
}

unsigned __stdcall ThreadFn(void*)
{
    counter--;
    ::SetEvent(event);
    return 0;
}

void Run()
{
    ::ResetEvent(event);
    counter = 1000;

    while (counter > 0)
    {
        StartNextThread();
        ::WaitForSingleObject(event, INFINITE);
        ::ResetEvent(event);
    }
}
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
void StartNextThread()
{
UINT threadId = 0;
HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &ThreadFn, 0, 0, &threadId));
::CloseHandle(thread);
}

unsigned __stdcall ThreadFn(void*)
{
counter--;
::SetEvent(event);
return 0;
}

void Run()
{
::ResetEvent(event);
counter = 1000;

while (counter > 0)
{
StartNextThread();
::WaitForSingleObject(event, INFINITE);
::ResetEvent(event);
}
}
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
void StartNextThread()
{
    UINT threadId = 0;
    HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &ThreadFn, 0, 0, &threadId));
    ::CloseHandle(thread);
}

unsigned __stdcall ThreadFn(void*)
{
    counter--;
    ::SetEvent(event);
    return 0;
}

void Run()
{
    ::ResetEvent(event);
    counter = 1000;

    while (counter > 0)
    {
        StartNextThread();
        ::WaitForSingleObject(event, INFINITE);
        ::ResetEvent(event);
    }
}

Zeit liegt immer noch bei ~~ 0.13 ms pro Thread.
Selbst wenn ich nicht nur auf den Event, sondern auf das Thread-Object selbst warte, ändert sich nichts an der gemessenen Zeit:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Run()
{
    counter = 1000;

    while (counter > 0)
    {
        ::ResetEvent(event);
        UINT threadId = 0;
        HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &ThreadFn, 0, 0, &threadId));
        ::WaitForSingleObject(event, INFINITE);
        ::WaitForSingleObject(thread, INFINITE);
        ::CloseHandle(thread);
    }
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Run()
{
counter = 1000;

while (counter > 0)
{
::ResetEvent(event);
UINT threadId = 0;
HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &ThreadFn, 0, 0, &threadId));
::WaitForSingleObject(event, INFINITE);
::WaitForSingleObject(thread, INFINITE);
::CloseHandle(thread);
}
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Run()
{
    counter = 1000;

    while (counter > 0)
    {
        ::ResetEvent(event);
        UINT threadId = 0;
        HANDLE thread = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &ThreadFn, 0, 0, &threadId));
        ::WaitForSingleObject(event, INFINITE);
        ::WaitForSingleObject(thread, INFINITE);
        ::CloseHandle(thread);
    }
}


EDIT:

Und nochmal auf nem Athlon 4850e (2 * 2.5 GHz) getestet, Windows 2008 R2 64 Bit, 4 GB RAM: 0.095 ~ 0.11 ms pro Thread.

Es wäre natürlich möglich dass ältere bzw. 32 Bit Windows-Versionen hier schlechter abschneiden. Hab ich aber grad keine da zum testen...

EDIT2:

Core i5 2500T (4 * 2.3 ~ 3.3 GHz), Windows 7 64 Bit, 8 GB RAM: 0.043 ~ 0.049 ms pro Thread.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/


Zuletzt bearbeitet von hustbaer am 23:32:01 04.02.2012, insgesamt 2-mal bearbeitet
C/C++ Forum :: WinAPI ::  Einen Thread nach bestimmter Zeit unterbrechen   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.