2016-05-31 14 views
0

Ich schrieb einen C# -Code, um einen nicht verwalteten Thread zusammen mit anderen verwalteten Threads in Mono auszuführen. Der nicht verwaltete Thread ist in Echtzeit, da er mit Xenomai-Bibliotheken unter Verwendung eines Wrappers erstellt wird. Der nicht verwaltete Thread führt eine in C# (verwalteten Code) geschriebene Funktion aus. Ich sah, dass der Thread wegen der Prioritätsumkehrung vom GC blockiert wurde (ich vermutete), also versuchte ich nur feste Felder zu verwenden. Das Endergebnis wird jedoch nicht verändert. Natürlich arbeite ich auf Linux und ich verwende Mono-JIT-Compiler-Version 3.2.6Warum ein nicht verwalteter Thread in Mono wegen des Garbage Collectors eingefroren wird, während nur feste Felder verwendet werden?

Warum ein unmanaged Thread in Mono friert es aufgrund der Garbage Collector ein, während nur feste Felder verwenden?

Danke!

Dies ist die pseudo-fuction

function_thread(){ 
    fixed(my_fields){ 
      while(true){ 
       my_code_use_only_fixed_fields; 
      } 
    } 
} 

N.B. Die Mono-Laufzeitumgebung registriert automatisch alle Threads, die mit dem Garbage Collector aus der verwalteten Welt erstellt wurden. Für Entwickler, die Mono einbetten, ist es wichtig, dass sie alle zusätzlichen Threads, die sie erstellen, mit der Laufzeit registrieren, die verwaltete Objekte mit mono_thread_attach manipulieren. Sie können dieses Konzept in diesem

P.S. finden. Ich nehme an, dass der Thread nicht angeschlossen ist, dann weiß der Müllsammler nichts von seiner Existenz. Ich nehme das an, weil ich den Thread nicht angehängt habe.

+0

Muss Ihr nicht verwalteter Thread einen Rückgabewert von der verwalteten Funktion erhalten, die er aufruft? Wenn nicht, sollten Sie in Betracht ziehen, es nicht direkt von der nicht verwalteten Seite aus aufzurufen, sondern stattdessen den nicht verwalteten Thread zu verwenden, um einem anderen verwalteten Thread den Aufruf zu signalisieren (z. B. über Wait-Handles oder Ähnliches). – nicholas

+0

Die verwaltete Funktion wird nicht vom nicht verwalteten Thread aufgerufen, aber sie ist die Funktion des Threads. –

Antwort

0

Während Ihr nicht verwalteter Thread verwalteten Code ausführt, wird er wie jeder andere Thread vom GC beeinflusst. Der aktuelle Mono- (und MS.NET-) GC lässt GC nicht gleichzeitig mit verwaltetem Code laufen (außer vielleicht Finalizern). Es gibt keine Analyse, um herauszufinden, ob es sicher wäre, Code gleichzeitig auszuführen. Beachten Sie, dass es Unterschiede gibt, die auf dem von Ihnen verwendeten GC basieren (und das letzte Mal, als ich Monos GCs überprüft habe, sie waren immer noch sehr einfach - das ist schon eine Weile her), aber meines Wissens wird es immer sein ein Punkt, an dem jeder "user" -Thread gesperrt ist. Dies ist nicht grundlegend und könnte in einem benutzerdefinierten GC geändert werden, aber es ist sicherlich kein einfaches Problem, und es hat einen sehr begrenzten Nutzen. Wenn Sie GC-Pausen vermeiden möchten, dürfen Sie keinen verwalteten Code verwenden.

Und ich muss auch darauf hinweisen, dass die Verwendung fixed wird dazu neigen, zu verhindern, dass der GC ordnungsgemäß funktioniert - alles, was behoben ist nicht verfügbar während Heap-Komprimierung, die entweder Heap-Fragmentierung führt oder verhindern, dass GC Speicher zurückfordern im schlimmsten Fall.

+0

Der Thread ist nicht angeschlossen, dann weiß der Garbage Collector nichts von seiner Existenz. Wie blockiert GC den nicht verwalteten Thread? –

+0

@ G.Puglisi Was meinst du, "nicht angeschlossen"? Jedes Mal, wenn ein nicht verwalteter Thread verwalteten Code aufruft, wird er zwangsläufig mit dem GC verflochten (natürlich nur für die Dauer der Ausführung des verwalteten Codes). Und so etwas wie "nur diese wenigen Zeilen verwalteten Codes" gibt es nicht - jede Zuweisung beinhaltet zwangsläufig verwalteten Speicher und damit zum Beispiel den GC (selbst scheinbar unschuldige Dinge wie das Manipulieren von Strings oder das erstmalige Aufrufen einer Methode/eines Typs). Es gibt keine Möglichkeit, dass verwalteter Code zuverlässig funktioniert, wenn dies nicht der Fall ist. Vergessen Sie nicht, dass der gesamte verwaltete Code aus nicht verwaltetem Code stammt. – Luaan

+0

@LuaanDie Mono-Laufzeitumgebung registriert automatisch alle Threads, die mit dem Garbage Collector aus der verwalteten Welt erstellt wurden. Für Entwickler, die Mono einbetten, ist es wichtig, dass sie alle zusätzlichen Threads, die sie erstellen, mit der Laufzeit registrieren, die verwaltete Objekte mit mono_thread_attach manipulieren. Sie finden dieses Konzept in diesem [link] (http://www.mono-project.com/docs/advanced/garbage-collector/sgen/) –

0

In der MS .NET Runtime werden nicht verwaltete Threads, die auf die Laufzeit zugreifen, automatisch als verwaltete Threads registriert. Ich wäre überrascht, wenn Mono das anders macht.

Dieses Verhalten wird here dokumentiert:

Wenn ein nicht verwalteter Thread die Laufzeit eintritt ... überprüft das System der lokalen Thread-Speicher von diesem Thread für ein internes verwalteten Thread-Objekt zu suchen. Wenn einer gefunden wird, ist der Laufzeit dieses Threads bereits bekannt. Wenn es jedoch keinen finden kann, erstellt die Laufzeitumgebung ein neues Thread-Objekt und installiert es im Thread-lokalen Speicher dieses Threads.

aber sagte, dass, wenn sie erstellt wird, kann ein reines GC freies Gewinde, ein reiner nicht verwalteten Faden haben, ist erwünscht, die mit einem ‚runner‘ Faden durch Standard asynchrone Programmiermuster verwalten in Wechselwirkung tritt, beispielsweise Griffe warten, Shared Memory usw.