Autor Beitrag
ironhaert
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mi 05.05.10 09:53 
Guten Morgen,
ich habe eine Semaphore in einer sogenannte BlockingQueue um die Threadsicherheit zu gewährleisten.
Änlich der Queue hier:
ausblenden volle Höhe C#-Quelltext
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:
class BlockingQueue<T>
    {
        private Queue<T> queue = new Queue<T>();
        private Semaphore semaphore = new Semaphore(01);
        private int maximumThreads = 1;
        public BlockingQueue(int maximumThreads)
        {
            semaphore = new Semaphore(0, maximumThreads); this.maximumThreads = maximumThreads;
        }
        public void Enqueue(T data)
        {
            if (data == nullthrow new ArgumentNullException("data");
            lock (queue)
            {
                queue.Enqueue(data);
                if (queue.Count() + 1 < maximumThreads)
                {
                    Console.WriteLine("Sem wurde released um 1 von " + semaphore.Release(1));
                }
            }
        }

        public T Dequeue()
        {
            {
                Console.WriteLine(Thread.CurrentThread.Name + " kommt zum Warten...");
                semaphore.WaitOne();
                Console.WriteLine(Thread.CurrentThread.Name + " geht aus Warten raus...");
                lock (queue) return queue.Dequeue();
            }
        }
    }

Da bei mir das Semaphore allerdings auf ne bestimmte Anzahl und eine maximale an Threads beschränkt ist, welche die mit dem Inhalt der Queue dementsprechend weiterarbeiten, sammeln sich bei mir an der Wait-Hürde (semaphore.WaitOne) in der Methode Dequeue viele wartende Threads an.
Da bei einem Release ja ein zufälliger Thread geweckt bzw. weitergelaufen lassen wird, ist eine Reihenfolge des Threadweiterlaufs nicht gewährleistet. Dies würde ich jedoch gerne erreichen.

Wie kann hier nun eine solche Reihenfolge gewährleistet werden(also, dass wenn die Threads in der Reihenfolge 1,2,3 zum Warten kommen; dass sie auch dementsprechend bei einem Release wieder frei gelassen werden)?
Ist dies im obigen Beispiel so überhaupt möglich?

Oder gibt es eine gute Alternative um de Ansatz einfacher umzustetzen?

Grüße,
ironhaert
Tryer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 226
Erhaltene Danke: 7



BeitragVerfasst: Mi 05.05.10 14:25 
Nehmen wir mal an alle drei Threads arbeiten. Dann werden zuerst Thread3, dann Thread2 fertig. Die sollen jetzt untätig bleiben bis Thread1 fertig ist?
Der Vorteil der mehreren Threads geht dabei größtenteils verloren, das kann man (fast) mit einem Thread erreichen. Angenommen die Threads wollen zur Beginn ihrer Arbeit eine Datei jeweils eine Datei auf der Platte öffnen, dann behindern sie sich zusätzlich durch gegenseitiges Warten und danach wieder fast zeitgleichen Zugriff auf die Platte.

Wenn sich "viele" Threads ansammeln, dann sind die Lasten ggf. falsch verteilt oder es sind einfach zu viele Arbeiter für zu wenig Jobs.

Wenn du denkst mehrere Threads machen Sinn, dann erstelle vielleicht noch einen zusätzlichen der die Ergebnisse entgegennimmt und solange zurückhält bis diese in der richtigen Reihenfolge vorliegen.

Grüsse, Dirk
ironhaert Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mi 05.05.10 16:35 
Hallo Tryer,
erst mal danke für deine Antwort. Um dir das mein Ansatz bei der Queue vielleicht noch etwas näher zu bringen, sollte ich vielleicht doch ein bisschen was dazu erzählen.

Ich dachte mir das ganze so, dass ich Generizität, Parallelität und kritische Objekte in dieser BlockingQueue unterbringen kann:
T1,T2,T3, sind Prozesse die alle schön ihre eigenen Aufgaben(Ablauf kann verschieden sein) A1,A2,A3 ... Ax abarbeiten(wobei T1.Aj != T2.Aj aber beides Instazen des selben Typs sind).
Innerhalb dieser Aufgabeabfolge gibt es die Aufgabe Ai (irgendeiner dieser Arbeitsschritte), welches nicht parallel ist oder nur bedingt, also in einer bestimmten Anzahl parallel ausführbar (daher die Beschränkung maximumThreads).
Daher sollen weiteren Threads nicht das enqueuen der Aufgabe verboten bleiben und warten bis Ai wieder für einen weiteren Thread verfügbar ist.
...
Zitat:
Wenn du denkst mehrere Threads machen Sinn, dann erstelle vielleicht noch einen zusätzlichen der die Ergebnisse entgegennimmt und solange zurückhält bis diese in der richtigen Reihenfolge vorliegen.

Ich weiß nicht, ob ich das richtig verstanden habe, aber ich hatte gerade ne Idee dazu. Werd ich aufjedenfall mal testen und meine Ergebnisse dazu dann euch mitteilen.

Generell haben sich hier ich noch ein paar Fragen welche ich allerdings in einem neuen Thread(hihi) hier untegebracht habe.

Grüße,
ironhaert
Tryer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 226
Erhaltene Danke: 7



BeitragVerfasst: Mi 05.05.10 17:21 
Zur Verwaltung von Ai einen Thread TJobCenter erstellen bei dem sich T1..n in eine (threadsichere) TThreadList eintragen. TJobCenter gibt den nächsten "freien Platz" dann an den T1..n der am Listenanfang steht (der am längsten wartet).

Grüsse, Dirk