pthread probléma

 ( Flatron | 2011. január 11., kedd - 13:53 )

Üdv!

Sajnos nem vagyok jártas C/C++ területén, de most rákényszerültem, hogy azt használjak. Maga a főalkalmazás Java, és a problémás kódot JNI-vel hívja. Erre azért van szükség, mert se kedvem, se néhány szabad évem nincs átírni java-ra a nauty nevű, gráfos dolgokkal foglalkozó programot (el kéne végezni hozzá egy matek Bsc-t minimum).

Maga a lib hívása nem bonyolult, és az stabilan működik (megközelítőleg olyan egymilliárd alkalommal már lefutott hiba nélkül). A probléma azzal van, hogy van, amelyik gráfot nehéz megoldani, de lehet használni a nauty-ban ún. invariánsokat, ezek kb heurisztikák. Némelyik eset elég szélsőséges, van, amit egy nap után lelőttem, és egy másik invariánssal egy fél szempillantás alatt lefutott, viszont a fordítottjára is van példa, úgyhogy azt kellene megoldanom, hogy ha nem fut le simán x idő alatt, akkor lője le, és számolja ki a másik invariánssal. Itt jönnek be a pthread-ek (java-ból ugyanis nem lehet lelőni a natív thread-et).

Sajnos az nem megoldható, hogy minden számításra külön thread-et nyitok, mert hetven valamennyi után a pthread_create resources temporary unavailable hibával hasal el. (Úgy 10-12000 hívás/sec a thread nélküli tempó), így azt találtam ki, hogy lenne egy worker thread, aminek a másik szál jelez, ha van meló, ha pedig gond van, akkor lelövi, és újranyitja a thread-et.

A program jelenlegi állapota itt található: http://pastebin.com/QyxSqCBe

A kimenet az alábbi:

Native init
Job wait
[Java output] ...
Job signal sent
Result wait
Job signal got
22 22

Tudom, nem szép dolog konzolra debuggolni, de sajnos a jni miatt kicsit körülményes a sima debug. Lényeg, hogy az init függvény lefut hiba nélkül, a munka jelzés is elküldésre kerül, sőt, meg is kapja a másik szál, viszont az eredményre várakozáshoz használt rc = pthread_cond_timedwait(&result_cond, &result_mutex, &waitTime); // Wait for the result (276. sor) 22-es hibával tér vissza, ami EINVAL.

A'la manual:

The pthread_cond_timedwait() and pthread_cond_wait() functions may fail if:

EINVAL The value specified by cond, mutex, or abstime is invalid.

EINVAL Different     mutexes     were     supplied    for    concurrent pthread_cond_timedwait() or  pthread_cond_wait()  operations  on the same condition variable.

Ez azért érdekes, mert a mutexre 2 sorral előtte lock-ol hiba nélkül, a cond ugyanúgy lett létrehozva, mint a másik, ami működik, a time ugyanígy működött az előző változatban (ami 1 szál/munka alapon működött), és mivel egy mutex van, így nem is tudnám különbözővel használni.

Ha valakinek van ötlete, mi nyomhatja a drágám lelkét, ne tartsa magában... Előre is köszi.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

up

ket dolgot latok hirtelen +/- par sorban a kerdeses resznel:
- a timespec-ben (waitTime) a tv_nsec-nek nincs kezdeti erteke. ez egy automatikus valtozo (272. sorban hozod letre), igy az objektum (bocsanat, struktura) tv_sec es tv_nsec tagjai random ertekekkel rendelkeznek. a tv_sec-nek adsz is erteket, az oke, de a tv_nsec-nek? az ugye csak 0 es 999999999 kozott lehet valami, tehat `long int` tipus mellett (lasd /usr/include/time.h) 32biten kb. 82%, 64biten pedig 99.9999...% hogy fals erteket fog tartalmazni, es ez siman dobhat EINVAL-t.
- pthread_cond_timedwait() lelkivilagat igy hirtelen nem latom at (reg volt :/) de a kapcsolodo mutexet muszaj elotte lefognod (275. sor)? rtfm alapjan ez igy most nem vilagos elsore. bar a pelda alapjan jonak tunik.

de persze egy 300+ soros kodot azert nehezebb kivesezni, ha nem te irtad...

szerintem is a tv_nsec környékén lehet a probléma.

leírás szerint:
EINVAL
Can be one of the following error conditions:
# The value specified by cond is not valid.
# The value specified by mutex is not valid.
# The value specified by abstime (tv_sec) is not valid.
# The value specified by abstime (tv_nsec) is not valid.
# Different mutexes were specified for concurrent operations on the same condition variable.
# The mutex is not owned by the current thread.

én valami ilyesmit csinálok egy multithreades programomban:

time( &now);
t.tv_sec  = now + 10;
t.tv_nsec = 0;

TTIP4 trc( "pthread_cond_timedwait() -->\n");
rslt = pthread_cond_timedwait( &thread->cond, &thread->lock, &t);
TTIP4 trc( "pthread_cond_timedwait() <-- (rslt=%d)\n", rslt);
if ( rslt && errno != EAGAIN)
{
   log( -1, "pthread_cond_timedwait() error, %d-%s",
                                  errno, strerror( errno));
}