Wie verwenden Sie printf() in mehrere threads
Ich bin Implementierung einer Multithread-Programm, das mit verschiedenen Kernen, und viele threads gleichzeitig ausgeführt werden. Jeder thread stellt eine printf()
nennen, und das Ergebnis ist nicht lesbar.
Wie kann ich printf()
atomaren, so dass eine printf()
Aufruf in einem thread nicht in Konflikt mit einem printf()
Gespräch in einer anderen?
nicht sicher, was Sie sagen wollen. Aber Wie kann ich es tun, ohne einen libraray, ich meine, wie Sie mithilfe von Semaphoren etc..
Wie über das erstellen einer
Definition von "Konflikt".
Nicht sicher, was Sie sagen, ist wahr. Ich dachte, dass der Puffer von printf können beeinflusst werden durch andere threads
Zeigen Sie ein code-Beispiel, das veranschaulicht das problem. Wie @Duck, ich habe nie gesehen, dass zwei
Wie über das erstellen einer
printf
Verpackung-Funktion und mit einem mutex?Definition von "Konflikt".
printf
ist "atomic" in dem Sinne, dass Sie bedeuten, aber es kann nicht aufhören, mehrere threads schreiben auf den gleichen Ausgang Ziel.Nicht sicher, was Sie sagen, ist wahr. Ich dachte, dass der Puffer von printf können beeinflusst werden durch andere threads
Zeigen Sie ein code-Beispiel, das veranschaulicht das problem. Wie @Duck, ich habe nie gesehen, dass zwei
printf
schreibt vermischt.InformationsquelleAutor user3242743 | 2014-05-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
POSIX-Spezifikationen
POSIX-Spezifikation umfasst die folgenden Funktionen:
getc_unlocked()
getchar_unlocked()
putc_unlocked()
putchar_unlock()
Die Spezifikation für diese Funktionen zu erwähnen:
flockfile()
ftrylockfile()
funlockfile()
Die Spezifikation für
flockfile()
et al schließt die Decke Anforderung:Dieser ersetzt den vorgeschlagenen code in früheren Ausgaben dieser Antwort. Der POSIX-standard legt auch fest:
Dort sind auch die Spezifikationen für die Zeichen-I/O-Funktionen:
getc()
getchar()
putc()
putchar()
fgetc()
fputc()
Die formatierte Ausgabe-Funktionen werden hier dokumentiert:
printf()
Eine zentrale Bestimmung in den
printf()
Spezifikation:Beachten Sie die Verwendung von 'als ob'. Jedoch, jeder der
printf()
Funktionen ist erforderlich, um die sperren so, dass der Zugang zu einem Strom gesteuert wird, die in einer multi-threaded-Anwendung. Nur ein thread zu einem Zeitpunkt kann mit einer bestimmten Datei-stream. Wenn die Operationen sind user-level-Aufrufefputc()
, dann können andere threads einstreuen, die Ausgabe. Wenn die Operationen sind user-level-Aufrufe wieprintf()
, das ganze dann anrufen und alle den Zugriff auf die stream-Datei ist tatsächlich geschützt, so dass nur ein thread ist, es zu benutzen, bis der Anruf zuprintf()
gibt.In den Abschnitt der System-Schnittstellen: Allgemeine Informationen Abschnitt POSIX zum Thema Threads, es sagt:
Die Liste der ausgenommenen Funktionen nicht enthalten
fputc
oderputc
oderputchar
(oderprintf()
et al.).Interpretation
Umgeschrieben 2017-07-26.
printf()
konzeptionell nennenflockfile()
am Anfang einfunlockfile()
am Ende, was bedeutet, dass die POSIX-definierten stream-Ausgabe-Funktionen werden auch thread-safe pro Anruf.flockfile()
undfunlockfile()
auf den entsprechenden stream (ohne sich mit der Verwendung des Systems die*lockfile()
Funktionen.Dies bedeutet, es gibt keine Notwendigkeit zu schaffen, Mutexe oder gleichwertige Mechanismen für sich selbst; die Umsetzung stellt die Funktionen ermöglichen Ihnen die Steuerung der Zugang zu
printf()
et al in einer multi-threaded-Anwendung....Code vom vorherigen Antwort entfernt, da nicht mehr relevant...
Haben Sie sich in der
flockfile()
Spezifikation verknüpft in der Antwort? Ich glaube, es sagt ja ganz ausdrücklich, wie zitiert in der Antwort — Alle Funktionen, die ReferenzFILE *
Objekte ... Verhalten, als wenn Sieflockfile()
undfunlockfile()
intern zum Erwerb des Eigentums an diesen (FILE *
) Objekte. ich grant Sie, die von einem halbwegs gut versteckt Standort für eine solche grundlegende Anforderung, aber das ist, wo der POSIX-standard sagt "user-level-Aufrufe wieprintf()
[sind] wirksam geschützt werden".Es sagt nur, dass die Eigentümerschaft muss erhalten werden, nicht, es muss gemacht werden kontinuierlich durch den Anruf. Es sieht für mich wie eine printf-Implementierung, fiel das Schloss und die zurückerworbenen es gelegentlich würde immer noch halten, um den Brief der Anforderung. Solange hielt er die Sperre über den tatsächlichen Ausgang würde es noch genügend Konsistenz für die zugrunde liegenden Objekte, aber es würde nicht verhindern, dass interleaving.
Ich glaube nicht, dass die standards committee hatte erwartet, Praktiker zu sein, so...pervers? hinterhältig?...zu denken, die nicht die Sperre auf der Datei stream in der gesamten Anruf. Sie könnten versuchen, indem Sie eine Implementierung, die sich verhielten, wie Sie vorschlagen, aber ich denke, Sie würden schnell feststellen, dass der QoI (Qualität der Umsetzung) wurde als "ungenügend" durch Nutzer, die würde aufhören, es zu benutzen. Die Absicht ist ziemlich klar, dass, sollte der code-Sperre den stream auf den Eintrag (oder zumindest vor der ersten Verwendung der stream selbst) und entsperren Sie es, bevor Sie return (oder zumindest nach der letzten Verwendung der stream selbst).
Fair genug! Ich denke, es ist die Aufgabe der Normungsgremien zu schreiben perversion-Nachweis Sprache, und es würde nicht schwer sein in diesem Fall. Aber ich bin mir nicht kommen mit einem guten Grund, warum würde jemand brauchen, um die drop-lock vorübergehend mid-print, also ich bin sicher, Sie sind richtig, dass niemand tut, dass....
InformationsquelleAutor Jonathan Leffler
Um keine für den mix des outputs von verschiedenen threads, die Sie benötigen, um sicherzustellen, dass nur ein thread verwendet
printf
zu einer Zeit. Um dies zu erreichen, die einfachste Lösung ist die Verwendung einesmutex
. Am Anfang initialisieren dermutex
:Dann einen wrapper um
printf
um sicherzustellen, dass nur der thread, hab denmutex
nennen kannprintf
(sonst wird es zu blockieren, bis diemutex
verfügbar ist) :Es sollte keine Notwendigkeit zu definieren, Ihre eigenen sperren, wie es bereits standard-Funktionen; siehe z.B. gnu.org/software/libc/manual/html_node/Streams-and-Threads.html (die auch behauptet, dass printf auf seine eigene, garantiert atomar sind. Ich weiß nicht, ob das stimmt.)
InformationsquelleAutor Grapsus
Für linux ,hier ist der code für u in c:3 threads ,die Ausführung auf unterschiedlichen Kernen drucken Hallo Welt ,nicht in Konflikt mit einander courtisey der Sperre .
InformationsquelleAutor Nasir Ul Islam Butt