windows - Deadlocks med pthreads og CreateThread

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg bruger pthreads i en Windows-applikation. Jeg bemærkede, at mit program var deadlocking - en hurtig inspektion viste, at følgende var sket:


Gevind 1 udgjorde tråd 2. Gevind 2 fremspringede tråd 3. Gevind 2 ventede på en mutex fra tråd 3, som ikke var låst op.


Så jeg gik til debug i gdb og fik følgende, når jeg trak den tredje tråd tilbage:


Thread 3 (thread 3456.0x880):
#0  0x7c8106e9 in KERNEL32!CreateThread ()
   from /cygdrive/c/WINDOWS/system32/kernel32.dll
Cannot access memory at address 0x131


Det var fastlåst, på en eller anden måde i Windows CreateThread-funktionen! Det kunne tydeligvis ikke låse op for mutexen, da det ikke var muligt at begynde at køre kode. Alligevel, på trods af at det tilsyneladende var fast her, returnerede pthread\_create nul (succes).


Hvad der gør dette særligt underligt er, at den samme applikation på Linux ikke har sådanne problemer. Hvad i verden ville få en tråd til at hænge under skabelsesprocessen (!?), Men returnere med succes som om den var blevet oprettet korrekt?


Rediger: Som svar på anmodningen om kode, her er nogle kode (forenklet):


Oprettelsen af ​​tråden:


if ( pthread\_create( &h->lookahead->thread\_handle, NULL, (void *)lookahead\_thread, (void *)h->thread[h->param.i\_threads] ) )
{
    log( LOG\_ERROR, "failed to create lookahead thread
");
    return ERROR;
}
while ( !h\_lookahead->b\_thread\_active )
    usleep(100);
return SUCCESS;


Bemærk, at det venter, indtil b\_thread\_active er indstillet , så på en måde bliver b\_thread\_active indstillet, så tråden bliver kaldt skal have gjort noget ...


... her er lookahead\_thread funktionen:


void lookahead\_thread( mainstruct *h )
{
    h->lookahead->b\_thread\_active = 1;
    while( !h->lookahead->b\_exit\_thread && h->lookahead->b\_thread\_active )
    {
        if ( synch\_frame\_list\_get\_size( &h->lookahead->next ) > delay )
            \_lookahead\_slicetype\_decide (h);
        else
            usleep(100);  // Arbitrary number to keep thread from spinning
    }
    while ( synch\_frame\_list\_get\_size( &h->lookahead->next ) )
        \_lookahead\_slicetype\_decide (h);
    h->lookahead->b\_thread\_active = 0;
}


lookahead\_slicetype\_decide (h); er den ting, som tråden gør.


Mutex, synch\_frame\_list\_get\_size:


int   synch\_frame\_list\_get\_size( synch\_frame\_list\_t *slist )
{
    int fno = 0;

    pthread\_mutex\_lock( &slist->mutex );
    while (slist->list[fno]) fno++;
    pthread\_mutex\_unlock( &slist->mutex );
    return fno;
}


Backtrace af tråd 2:


Thread 2 (thread 332.0xf18):
#0  0x00478853 in pthread\_mutex\_lock ()
#1  0x004362e8 in synch\_frame\_list\_get\_size (slist=0x3ef3a8)
    at common/frame.c:1078
#2  0x004399e0 in lookahead\_thread (h=0xd33150)
    at encoder/lookahead.c:288
#3  0x0047c5ed in ptw32\_threadStart@4 ()
#4  0x77c3a3b0 in msvcrt!\_endthreadex ()
   from /cygdrive/c/WINDOWS/system32/msvcrt.dll
#5  0x7c80b713 in KERNEL32!GetModuleFileNameA ()
   from /cygdrive/c/WINDOWS/system32/kernel32.dll
#6  0x00000000 in ?? 

Bedste reference


Jeg ville prøve dobbelt kontrol af dine mutexes i tråd 2 og tråd 3. Pthreads implementeres for windows ved hjælp af standard windows api; Så der vil være små forskelle mellem Windows og Linux versioner. Dette er et bizarre problem, men så igen sker der meget i tråde.


Kan du prøve at indsende et kodestykke af koden, hvor låsningen sker i tråd 2, og i den funktion, at tråd 3 skal starte?


Rediger som svar på kode


Har du nogensinde låst mutexet i tråd 2? Dit spor viser, at det låser en mutex og derefter opretter en tråd for at gøre alt det arbejde, der forsøger at også låse på mutexen. Jeg gætter efter, at tråd 2 returnerer SUCESS det gør også, hvorfor bruger du flag og sovende, måske er barrierer eller betingede variabler til processynkronisering mere robuste.


En anden note, er b\_thread\_active flag markeret som flygtig? Måske kører kompilatoren noget for ikke at tillade det at bryde ud?