Ipari zen

Szak-irodalom. A fejlesztő jajszava haikuban. A technika ördöge avagy a lelketlen vasban a mélyen emberi.

A szoftverfejlesztés művészete és a zen

2010.02.19. 12:30 Ipari zen

A többszálas programozás buktatóiból

Címkék: többszálú szál multithreading konkurrens

Szoros a verseny,
nagy a tét.
Nem ok rá, hogy
megelőzd magad.


Valószínüleg pályafutásom legperverzebb hibajelenségét sikerült izolálni a múlt héten.  Az történt ugyanis, hogy egy laborban pöpecül zakatoló linux kernel modul azonnal feldobta a talpát, mikor a számára oly kellemes és megszokott környezetből kihoztuk egy irodába, ahol egy demo erejéig szerettük volna üzemeltetni. Ha visszavittük azonnal meggyógyult, ha kihoztuk megint beteget jelentett és azonnal lefagyott tőle az egész gép.

Ha printk-kal láttuk el a modul vezérlőszálát, akkor kint is működött, ha kivettük a printk-kat akkor megint nem. Napok teltek bele míg sikerült a problémára fényt deríteni.

Történelmi előzményként annyit kell tudni, hogy a kernel modul kimenetét két másik user space modul vezérelte egy parancsértelmezőn keresztül. Mikor ezeket megírtuk némi gondolkodás után azt mondtuk, hogy a "start output" parancs kiadása benne maradhat mind a két vezérlőmodulban, hiszen nem okozhat gondot, ha a
kétszer is kimegy egymás UTÁN, mert egy flaggel védve van, hogy ne fusson le kétszer a parancsértelmező.
Mondom UTÁN. Ugyanis a kiadott parancsok szekvencialitását
semmi sem garantálta a kernel modulon belül és minden parancs kiadása
külön szálon futott végig. Emiatt aztán, ha elég meleg volt és a processzor nem volt elég fürge a parancsok EGYSZERRE, párhuzamosan futottak végig.
A parancs hatására a következő dolgok kellene történjenek:

első futás
output flag vizsgálata  (amennyiben 1x már lement akkor mégegyszer ne fusson)
régi output bufferek letörlése
új bufferek létrehozása
output flag beállitása

Másodszori futáskor az első sornál kilép.

Azonban a parancsok párhuzamosan futottak,
pl így és ebben az esetben semmi gondot nem okozott a jelenség

output flag megnéz1
buffer törlés 1
buffer létrehozás 1          output flag megnéz 2
output flag beállít 1         buffer törlés 2
                                      buffer létrehozás 2
                                      output flag beállít 2

Amikor viszont a vaksors úgy hozta, hogy nem volt ekkora nagy a csúszás a 2 szál között,
akkor viszont a következő dolog történt.

output flag megnéz1
buffer törlés 1              output flag megnéz 2
                                   buffer törlés 2
buffer létrehozás 1
output flag beállít 1       buffer létrehozás 2
                                   output flag beállít 2

Így aztán ugyanazt a területet szépen felszabadítottuk 2x és az egész kernel hátast dobott.
A megoldás persze az, hogy minden parancs lockolja a parancsértelmező függvényt, míg teljes mértékben végig nem futott.

 

Szólj hozzá!

A bejegyzés trackback címe:

https://ipari-zen.blog.hu/api/trackback/id/tr801642331

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.