2012-08-16 4 views
6

Ich habe viele C-Programme für Mikrocontroller geschrieben, aber nie eine, die auf einem Betriebssystem wie Linux läuft. Wie entscheidet Linux, wie viel Bearbeitungszeit meine Bewerbung benötigt? Gibt es etwas, was ich tun muss, wenn ich ungenutzte Zeit habe, dem Betriebssystem zu sagen, etwas anderes zu tun und später zu mir zurück zu kommen, damit andere Prozesse auch Zeit zum Laufen bekommen? Oder macht das OS das einfach automatisch?Was sollte das C-Programm im Leerlauf tun, wenn es unter Linux läuft?

Bearbeiten: Hinzufügen von weiteren Details Mein c-Programm verfügt über einen Taskplaner. Einige Aufgaben werden alle 100 ms ausgeführt, andere alle 50 ms und so weiter. In meiner Hauptprogrammschleife rufe ich ProcessTasks auf, die prüfen, ob irgendwelche Aufgaben bereit sind zu laufen, wenn keine bereit sind, ruft sie eine Leerlauffunktion auf. Die Idle-Funktion macht nichts, aber es ist da, um einen GPIO-Pin umzuschalten und die Leerlaufzeit mit einem Oszilloskop zu überwachen ... oder etwas, wenn ich es möchte. Also sollte ich vielleicht sched_yield() in dieser Leerlauffunktion aufrufen ???

Antwort

6

Wie Linux entscheiden, wie viel Bearbeitungszeit meine Anwendung geben

Jeder Scheduler macht seine eigene Meinung. Einige belohnen Sie, weil Sie Ihren Anteil nicht aufgebraucht haben, einige Rollwürfel versuchen zu prognostizieren, was Sie tun werden etc. Meiner Meinung nach können Sie nur betrachten es magisch. Nachdem wir die Schleife betreten, entscheidet der Scheduler magisch unsere Zeit ist oben usw..

Gibt es etwas, was ich tun müssen, wenn ich Leerlaufzeit haben das Betriebssystem zu sagen zu gehen, etwas anderes tun

Sie sched_yield nennen könnte. Ich habe es nie genannt, und ich kenne auch keine Gründe, warum man es möchte. Das Handbuch sagt jedoch, es könnte die Leistung verbessern.

Oder hat das Betriebssystem genau das tun automatisch

Es sicherlich der Fall ist. Deshalb nennen sie es "preemptive" Multitasking.

+0

So die anderen Antworten sagen Schlaf zu verwenden (). Soll ich sleep() und sched_yield() aufrufen? wenn ja, in welcher sollte zuerst aufgerufen werden? – PICyourBrain

+0

@PICyourBrain Lesen Sie das Handbuch. Der Ertrag wird Ihren Prozess laufen lassen, wenn nichts anderes zu tun ist, während 'sleep' eindeutig Ihren Prozess warten lässt. – cnicutar

+0

Wenn Sie einen Spinlock implementieren, möchten Sie sleep (0) oder sched_yield() jedes Mal aufrufen, wenn die Sperre nicht ausgeführt werden kann. – Arvid

5

Es hängt davon ab, warum und wie Sie "Leerlaufzeit" haben. Jeder Aufruf einer blockierenden E/A-Funktion, die auf einen Mutex wartet oder schläft, entlädt automatisch den Thread und lässt das Betriebssystem mit etwas anderem fertig werden. Nur etwas wie eine geschäftige Schleife wäre ein Problem, aber das sollte auf keinen Fall in Ihrem Design erscheinen.

Ihr Programm sollte eigentlich nur eine zentrale "Endlosschleife" haben. Wenn es eine Chance gibt, dass der Schleifenkörper "keine Arbeit mehr hat", dann wäre es am besten, wenn Sie die Schleife dazu bringen würden, eine der obigen Systemfunktionen auszuführen, die alle Schönheiten automatisch erscheinen lassen würden. Wenn Ihre zentrale Schleife beispielsweise eine epoll_wait ist und alle Ihre E/A, Timer und Signale von epoll verarbeitet werden, rufen Sie die Funktion mit einem Timeout von -1 auf, um sie einzuschalten, wenn nichts zu tun ist. (Im Gegensatz dazu würde es bei einem Timeout von 0 zu einem Busy-Loop – führen!).

+0

Ich habe mehr Informationen zu meiner Frage hinzugefügt – PICyourBrain

+1

@PICyourBrain: Es klingt, als könnten Sie all das mit epoll machen. Timer können über 'timerfd' eingerichtet werden, und ich nehme an, dass auch andere Ereignisse über Dateideskriptoren behandelt werden können. Auf einem "epoll_wait" schlafen zu gehen, ist eine effiziente Möglichkeit, die Leerlaufzeit zu vertreiben. –

1

Die anderen Antworten IMO gehen zu sehr ins Detail. Die einfache Sache zu tun ist:

while (1){ 
    if (iHaveWorkToDo()){ 
     doWork(); 
    } else { 
     sleep(amountOfTimeToWaitBeforeNextCheck); 
    } 
} 

Hinweis: Dies ist die einfache Lösung, die in einer Singlethread-Anwendung oder wie der Fall sein nützlich ist, wenn Sie etwas für eine bestimmte Menge an Zeit zu tun, nicht haben; nur um etwas Anständiges zu bekommen.Die andere Sache ist, dass der Schlaf die vom os bevorzugte Ertragsfunktion nennt, also in diesem Sinne besser ist als ein osspezifischer Renditeaufruf.

Wenn Sie auf hohe Leistung setzen möchten, sollten Sie auf Ereignisse warten.

Wenn Sie Ihre eigenen Veranstaltungen haben wird es etwas sein, wie folgt:

Lock *l; 
ConditionVariable *cv; 

while (1){ 
    l->acquire(); 
    if (iHaveWorkToDo()){ 
     doWork(); 
    } else { 
     cv->wait(lock); 
    } 
    l->release(); 
} 

In einer Netzwerktyp Situation wird es wie mehr sein:

while (1){ 
    int result = select(fd_max+1, &currentSocketSet, NULL, NULL, NULL); 
    process_result(); 
} 

+0

waitForSomeEvent statt nur schlafen – CyberDem0n

+0

@ CyberDem0n ja, ich habe den zweiten Teil versucht, wie Sie das kommentiert. Ich versuche nur, ein paar verschiedene Lösungen für Leute zu geben, die nicht zu weit in die Multithreading-Welt eintauchen wollen. Es scheint auch von der Frage, dass er nach Schlaf sucht. – chacham15

+0

@ chacham15 Ich vermute, du meinst l-> akquirieren und l-> release, richtig?> – PICyourBrain

Verwandte Themen