[ Boris B. @ 09.03.2011. 09:13 ] @
Ako imam više threadova u jednom .Net AppDomain-u, kako bih mogao da izmenjujem objekte između njih ako je jedini način komunikacije slanje poruka kroz unmanaged layer:

Code:

Thread1            Unmanaged layer           Thread2
======================================================
   |                      |                      |
   |                      |                      |
new A()                   |                      |
   |                      |                      |   
   |                      |                      |   
Send(A)  ----------->   Rcv(A)                   |
   |                      |                      |   
   |                      |                      |   
EndThread()          Enqueue(A)                  |
                          |                      |   
                          |                      |   
                        Send(A)  ----------->  Rcv(A)
                                                 |
                                                 |
                                                ...

Unmanaged layer zna da prima i šalje byte[]. Isto tako onaj koji šalje poruku ne zna koliko ima "slušalaca" za poruku, možda nema nijedan. Serijalizacija i deserijalizacija objekta jeste opcija, ali me na prvom mestu zanima da li postoji način da pretvorim referencu na objekat u nešto kao pointer, i da pritom prevarim GC da ne kolektuje taj objekat, pošto neko vreme dok je u queue-u umanaged layera niko u AppDomainu nece imati refrenecu na njega. Pada mi na pamet i neki resource manager koji ce da bude zaduzen za kreiranje i referenciranje objekata, ali je u tom slucaju problem kako znati trenutak kada treba pustiti referencu.
[ Shadowed @ 09.03.2011. 10:10 ] @
Mozda bi mogao da koristis neku thread-safe listu pa da prosledjujes index. Tako bi ujedno i odrzao referencu a kada Thread2 zavrsi sa tim objektom, moze ga izbaciti iz liste i tako ukinuti referenciranje.
Na taj nacin prosledjujes jedan int sto je na 32bit sistemu isto kao i reference a na 64bit upola manje. Jedino sto povecavas vreme dobijanja objeta koliko je listi potrebno da pronadje objekat po index-u, sto ne bi trebalo da je problem.
[ Boris B. @ 09.03.2011. 10:19 ] @
Slažem se, ali onda imam onaj problem:
Citat:
Boris B.: Pada mi na pamet i neki resource manager koji ce da bude zaduzen za kreiranje i referenciranje objekata, ali je u tom slucaju problem kako znati trenutak kada treba pustiti referencu.


EDIT: Da pojasnim jos malo, slušalaca za svaku poruku ima 0..N. Isto tako svaki thread ima inbox tj. message queue (ne windows message queue nego ZeroMQ), tako da u principu jedan thread može da pošalje objekat drugom i trećem, drugi ga dobije skoro odmah, a treći će tek posle pola sata jer mu je inbox pun neobrađenih poruka.
[ mmix @ 09.03.2011. 11:17 ] @
Mozes li da reorganizujes thread1 da waituje do Thread2/Rcv(A) i da onda Thread1 pozove GC.KeepAlive(A)?

Evo, npr mozes da iskoristis ManualResetEvent, Thread1 kreira MRE u nonsignaled stateu, kad saljes poruku A uz nju posalji i safeWaitHandle (to je unmanaged informacija) i posle uradi WaitOne(). Thread 2 kad primi pamet kreira svoj MRE sa istim handlom i pozove Set() da pusti Thread1. Thread1 iza wait ima poziv u KeepAlive(A) koji osigurava da se referenca A ne colectuje tokom celog svog puta.

[Ovu poruku je menjao mmix dana 09.03.2011. u 13:02 GMT+1]
[ mmix @ 09.03.2011. 12:09 ] @
Cek, ti koristis eksterni unmanaged MQ. Zasto ako su svi ucesnici u istom appdomenu? Zar nisi mogao da napravis neki interni MQ sistem ako vec nema gotovo. Ne verujem da ti treba vise od 30-50 linija koda da nrapravis interni queuing na nivou inbox threadova i radice mnogo brze.

[ Boris B. @ 09.03.2011. 12:58 ] @
@mmix: zato sto ZeroMQ ima ugrađen Post/Retrieve za unicast, ali i Broadcast/Retrieve za multicast i Fan/Sink za paralelno. Imam i svoje inproc MQ-ove od pre, ali za broadcast i fan treba daleko više posla nego za Post/Retrieve.

Ovaj MRE mi se čini da je to što mi treba, samo me zanima zašto mi treba GC.KeepAlive()? Ako će Thread1 da radi MRE.WaitOne, zar referenca neće biti živa, zdrava i referencirana doklegod je Thread1 živ?
[ mmix @ 09.03.2011. 13:02 ] @
Nece, GC scope nije na nivou metoda, cim prodje tacka poslednje upotrebe u metodi GC je slobodan da kolektuje referencu. KeepAlive posle Wait osigurava da referenca ostane ziva dok ti cekas Wait

Mada iskreno ja bi uradio i Fan :) al garant je neko vec uradio negde :)

Imaj u vidu doduse onda da ti MRE nece pomoci jer on funkcionise samo za 1-1. 1-many moze da radi kroz semafor ali moras da znas koliko subscribera imas da bi podesio semafor. Ako ti zeroMQ ne daje tu informaciju onda nazalost mislim da nemas nacin da izbegnes memory leak jer ne znas u managed kontekstu koliko referenci ce se pojaviti u kom trenutku.

[Ovu poruku je menjao mmix dana 09.03.2011. u 14:20 GMT+1]
[ Boris B. @ 09.03.2011. 13:18 ] @
Au boga mu, nisam znao za to. A jes' logično.

Anyways, neće mi ni to poleteti sa MRE zbog multicasta, morao bi da čekam na više primalaca, a pritom ne znam koliko ih ima. Čak i da je samo jedan primalac, šta ako moram da pošaljem 2 objekta...
Izgleda da ću morati da koristim serijalizaciju, što i možda i nije tako loše, jer onda džabe dobijem i out-of-proc primaoce, tj. lepo skalabilno

Edit: Pogledaj malo onaj MQ, pogotovu onaj uvod, meni izgleda fenomenalno.