Im Zeitalter der modernen Softwareentwicklung und -programmierung kann der Begriff „Laufzeit“ je nach Kontext und diskutierter Sprache unterschiedliche Bedeutungen haben. Ich bin hier, um diese Unterschiede zu verdeutlichen, und konzentriere mich dabei auf die Funktionsweise von Laufzeiten in C im Vergleich zu moderneren Sprachen wie Java oder Python. Ich beabsichtige, diesen Artikel auf Programmieranfänger zu konzentrieren, damit ich mich nicht mit komplexen Konzepten befasse.
Im Kern ist eine Laufzeit ein Programm selbst, das von einem Entwickler geschriebenen Code liest und ausführt. Es wird jedoch verwirrend, wenn einige Entwickler die Laufzeit mit der C-Sprache verwenden.
In Sprachen wie Java oder Python ist die Laufzeit ein Programm selbst, das Ihre myfile.js-Datei liest. Deshalb führen Sie nodejs-Programme aus wie: node myfile.js und v8 engine( ist die JavaScript-Engine, sie analysiert und führt JavaScript aus Code.) verwaltet alles dafür, ob Sie eine neue Datei erstellen, einen untergeordneten Prozess starten usw. und was am wichtigsten ist, Sie können nichts tun, was Ihnen Version 8 nicht erlaubt.
Aber wenn Sie ein C-Programm ausführen, führen Sie c myfile.c nicht aus, Sie müssen es nur einmal kompilieren und jetzt benötigen Sie kein gcc mehr, sondern führen es einfach direkt aus.
In C gibt es kein separates Programm, das neben Ihrem Code ausgeführt wird, so wie in Java oder Python. Stattdessen handelt es sich bei dem, was oft als C-„Laufzeit“ bezeichnet wird, tatsächlich um einen Satz statisch eingefügten Codes und Anweisungen, die während der Kompilierung hinzugefügt werden. Es handelt sich um einen minimalen Satz von Anweisungen, die in der endgültigen Binärdatei enthalten sind, um bestimmte notwendige Aufgaben auf CPU-/Betriebssystemebene zu erledigen. Es übernimmt die Erstellung und Demontage von Stack-Frames für Funktionsaufrufe (unter Verwendung von Anweisungen wie PUSH, POP, CALL, RET in Assembly). Selbst dies kann überschrieben werden, indem Sie Ihre eigene __start-Funktion mithilfe von Inline-Assembly bereitstellen, wodurch Entwickler vollständige Kontrolle über den Einstiegspunkt und die Initialisierung des Programms haben.
void __start() { // Custom entry point, no standard library initialization // You have no access to argc and argv here unless you access them manually from registers // you can create you own custom stack setup, initialization and etc here. // Exit directly using a syscall asm("mov $60, %rax; mov $0, %rdi; syscall"); // exit(0) syscall }
Das sieht überhaupt nicht nach Laufzeit aus, es ist nur ein vom Compiler hinzugefügter Assembler-Code, sodass Entwickler das nicht tun müssen.
In C können Sie Systemaufrufe direkt über Inline-Assembly aufrufen, um mit dem Kernel auf eine Weise zu interagieren, die das Betriebssystem normalerweise nicht zulässt. Auf diese Weise werden Malware erstellt. Mit der Inline-Assembly können Entwickler Assembler-Anweisungen innerhalb von C-Code schreiben. Dies wird häufig für leistungskritischen Code oder für den Zugriff auf bestimmte Hardwarefunktionen verwendet.
Unter Linux verfügt C über ein FLAG, mit dem Sie Dateidaten direkt auf ein Speichergerät schreiben können und dabei einige der Caching-Mechanismen des Kernels umgehen. Es heißt O_DIRECT-Flag und wird in Kombination mit den Systemaufrufen open und write verwendet. Dieses Flag stellt sicher, dass Daten nicht im RAM gepuffert oder vom Kernel im Kernelraum verwaltet werden. Dadurch werden die Daten direkt auf die Festplatte geschrieben. JVM lässt dies nicht zu, und das ist nur ein einfaches Beispiel.
Hier ist ein einfaches Beispiel:
asm volatile ( "syscall" : "=a" (written) : "0" (1), "D" (fd), "S" (buffer), "d" (BLOCK_SIZE) : "rcx", "r11", "memory" );
*Hinweis: * (geschrieben) ist eine in main() erstellte Variable, (1) ist die Systemaufrufnummer für das Schreiben, (fd) ist der Ort, an dem die Datei geschrieben wird, d. h. int fs = open("path .log",O_WRONLY; (BLOCK_SIZE) ist ein weiterer Variablenname. Er ist komplexer.
Es ist wichtig zu verstehen, dass sich das Konzept der Laufzeit im Laufe der Jahre weiterentwickelt hat. Die C-„Laufzeit“ der 70er Jahre unterscheidet sich stark von den robusten Laufzeitumgebungen, die wir in Sprachen aus den 2000er Jahren sehen. Diese Entwicklung kann bei der Diskussion von Laufzeiten zu Verwirrung führen, insbesondere zwischen Entwicklern, die mit verschiedenen Programmierepochen vertraut sind.
Ich denke, die Leute vergleichen jetzt die Laufzeiten der 1970er-Jahre mit den Laufzeiten der 2000er-Jahre, was dazu führt, dass neue Entwickler mit alten Entwicklern verwechselt werden.
Ein bestimmtes Problem zu lösen ist die Hauptaufgabe jeder Programmiersprache. Sie möchten kein ganzes Framework zum Erstellen von APIs in C schreiben. Wir haben NodeJS und es ist gut darin, und Sie müssen keinen Bare-Metal-Code in Javascript schreiben, weil wir Ich habe bereits C und es ist großartig darin. Warum das Rad neu erfinden, lasst uns die Räder nutzen und ein fantastisches Auto erschaffen, es sei denn, Sie möchten es nicht auf dem Mars fahren.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3