Fork-Join semaphore multiprocess c#

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • ZaZ
  • Registratie: Oktober 2002
  • Laatst online: 27-09 00:06

ZaZ

Tweakers abonnee

Topicstarter
Voorinformatie:
Ik heb hier een GUI applicatie die moet kunnen uitlezen welke taken er via een scheduled task draaien.
Die taken zijn console-apps. Het is moeilijk vast te stellen via de bestaande libraries van Windows en daarbij moet er ook nog IPC plaatsvinden.
Mijn idee was iets van; het eerste process is de aanmeld service waar iedereen zich op abonneert en die blijft leven zolang er nog andere processen zijn.
Met dit voorkom je een losse service die altijd moet draaien. TCP verkeer is niet mogelijk en het draait altijd op hetzelfde systeem, dus communicatie via named pipes geniet op dit moment mijn voorkeur.
Mijn vraag gaat dus over een proces wat blijft leven totdat alle andere relevante processen afgesloten zijn.

Mijn eerste idee was iets met semaphores te doen, maar heb eigenlijk een soort omgekeerde semaphore nodig.
Daar je met een semaphore makkelijk kan throttlen, wil ik juist locks krijgen totdat de queue leeg is.
Ik zoek eigenlijk zoiets als het CountDownEvent, maar dan 'named' omdat het multiprocess is.
Ik heb bij wijze van test effe iets in elkaar gehacked om het mechanisme te testen en dat werkt redelijk, maar voelt toch heel vies aan en ben benieuwd of er betere alternatieven zijn voordat ik dit uit ga werken.


C#:
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
 public static class ForkJoinSemaphore
    {
        static Semaphore _semaphore;
        static bool _owner;

        public static void Initialize()
        {
            _semaphore = new Semaphore(0, 999999999, "SOMEUNIQUESTRING", out _owner);
            if (!_owner)
            {
                //increase by 1
                _semaphore.Release();
            }
           
        }

        public static void WaitAndExit()
        {
            //owners should loop until the count == 0
            if (_owner)
            {
                //loop until the counter hits 0 ,but don't wait the lock
                while (_semaphore.WaitOne(0))
                {
                    //increase again as our 'check' has decreased the counter
                    _semaphore.Release();
                    Thread.Sleep(100);
                }
                _semaphore.Release(999999999);
            }
            else
            {
                //this will never wait unless the owner has been killed/died abruptly
                //decrease the counter by 1
                _semaphore.WaitOne();
            }
        }
    }


Dit is een 'kladje' maar het werkt al een beetje.
Elk proces roept de Initialize aan en voordat ie aflsuit de WaitAndExit.
Het eerst gestartte proces zal blijven wachten totdat de anderen ook zijn afgesloten en alle overige sluiten direct.

Het stuk wat me het meeste dwarszit is de loop met de sleep erin. Dat is heel lelijk.
Verder zijn er nog natuurlijk andere issues te verzinnen zoals het crashen van een proces en die zijn handle niet teruggeeft, maar dat is allemaal wel op te lossen.

Lekker op de bank


Acties:
  • 0 Henk 'm!

  • gekkie
  • Registratie: April 2000
  • Laatst online: 11-10 00:43
Zouden Back and foreground threads je uit de brand kunnen helpen ?
Of zijn het echt losse processen en geen threads ?

[ Voor 14% gewijzigd door gekkie op 30-07-2016 02:16 ]


Acties:
  • 0 Henk 'm!

  • ZaZ
  • Registratie: Oktober 2002
  • Laatst online: 27-09 00:06

ZaZ

Tweakers abonnee

Topicstarter
Het zijn echt losse processen.
Anders was ik er met het CountDownEvent volgens mij al geweest.

Lekker op de bank


Acties:
  • 0 Henk 'm!

  • gekkie
  • Registratie: April 2000
  • Laatst online: 11-10 00:43
Hmm hoofdproces laten blocken op een (extra) named pipe van de anderen ?

Acties:
  • 0 Henk 'm!

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 07-10 10:46
Hoe worden de processen opgestart? Kan je niet iets met het 'Exited' event van Process?

https://msdn.microsoft.co...ess.exited(v=vs.110).aspx

Acties:
  • 0 Henk 'm!

  • ZaZ
  • Registratie: Oktober 2002
  • Laatst online: 27-09 00:06

ZaZ

Tweakers abonnee

Topicstarter
epic007 schreef op zaterdag 30 juli 2016 @ 17:26:
Hoe worden de processen opgestart? Kan je niet iets met het 'Exited' event van Process?

https://msdn.microsoft.co...ess.exited(v=vs.110).aspx
Door de task scheduler van Windows, dus dat gaat niet.
gekkie schreef op zaterdag 30 juli 2016 @ 02:27:
Hmm hoofdproces laten blocken op een (extra) named pipe van de anderen ?
Die snap ik effe niet

Lekker op de bank


Acties:
  • 0 Henk 'm!

  • gekkie
  • Registratie: April 2000
  • Laatst online: 11-10 00:43
Hmm ik ook niet meer .. geloof dat ik iets ruik :$ .. breinscheetje :+

Acties:
  • 0 Henk 'm!

  • Lethalis
  • Registratie: April 2002
  • Niet online
Zien welke processen er door de Task Scheduler draaien, kun je met schtasks.exe:

MSDN: Schtasks.exe (Windows)

Daarvan zou je de output kunnen pollen in de gui app en hoef je de processen niet aan te passen.

Welke IPC moet er tussen de taken zelf en de gui plaatsvinden dan?

Ask yourself if you are happy and then you cease to be.


Acties:
  • 0 Henk 'm!

  • ZaZ
  • Registratie: Oktober 2002
  • Laatst online: 27-09 00:06

ZaZ

Tweakers abonnee

Topicstarter
Lethalis schreef op zondag 31 juli 2016 @ 09:06:
Zien welke processen er door de Task Scheduler draaien, kun je met schtasks.exe:

MSDN: Schtasks.exe (Windows)

Daarvan zou je de output kunnen pollen in de gui app en hoef je de processen niet aan te passen.

Welke IPC moet er tussen de taken zelf en de gui plaatsvinden dan?
Er is ook een API voor de task scheduler en dan kan ik ook wel de draaiende taken vinden maar dan nog moet er nog IPC plaatsvinden en moet er dus een soort master/manager zijn waar wordt bijgehouden wie wat is en hoe te bereiken.
Dit probleem is natuurlijk af te vangen door gewoon een service te draaien die dat doet maar dat is ook wat overkill.

Het soort IPC wat er is is een beetje als volgt:
De GUI en de console apps zijn hebben beiden dezelfde backend en kunnen grotendeels hetzelfde.
De GUI-app kan alleen ipv dingen zelf meteen uit te voeren ook dingen schedulen. Als er scheduled tasks draaien dan moet de GUI dat kunnen tonen en ook realtime informatie van die taken kunnen tonen en de taken kunnen stoppen etc.
Dat doe ik ook liever 'gracefully' door een cancellation token dan stomweg de taak te stoppen via de Windows API.
De hele communicatie is geen probleem, alleen het eerste-proces-is-server-en-moet-wakker-blijven stukje is lelijk.
Misschien toch maar gewoon een dedicated service gaan gebruiken of vrede sluiten met mijn omgekeerde semaphore hack, die ook gewoon werkt.

Ik hoopte eigenlijk dat iemand iets anders dan een semaphore wist een beetje zoals het CountDownEvent, maar dan 'named'

Lekker op de bank

Pagina: 1