2016-06-24 25 views
1

Entschuldigung, wenn diese Frage scheint ein bisschen offen oder zu vage, ich bin nicht der beste C/Cpp Programmierer (jede Sprache ist akzeptabel, um dies zu lösen Problem).Was ist der beste Weg für einen Server-Prozess auf Client-Eingabe/Nachrichten warten

Angenommen, es gibt zwei laufende Prozesse, einen Client und einen Server (sie könnten auch als Produzent und Verbraucher angesehen werden, aber ich denke, Client und Server könnten hier besser sein). Der Server ist ein "Kind" (so, siehe unten) Prozess des Clients, so dass er so erstellt wurde, dass er gewissermaßen als Entlastung fungiert. Im Laufe der Zeit erzeugt der Client mehrere Jobs, die er auf den von ihm erstellten Server auslagert. Abhängig vom Job kann der Server Informationen zum Abschluss des Jobs an den Client senden oder nicht. Nebenbei, einige könnten vorschlagen, dass dies mit Threads getan werden könnte. Aus Gründen, auf die ich nicht eingehen werde, funktionieren Threads hier nicht. Der Client und der Server sollten keinen gemeinsamen Speicher haben (es kann sein, dass Shared Memory vorhanden ist oder nicht, es ist möglich, dass der Client und der Server zwei verschiedene Maschinen sind: der Code, den ich schreibe, sollte beide Möglichkeiten unterstützen).

Der Server hat eine sehr lange Initialisierungsphase und muss daher immer ausgeführt werden, daher ist der zweite Prozess ein Server. Es muss daher immer auf Nachrichten des Clients warten. Ein einfaches Pseudo-Code/C-Beispiel ist unten angegeben

int main() { 
    ... 
    client_pid = getpid(); 
    pid = fork(); 
    if(pid > 0) { 
     /* sets up connection with client, based on what connection type has been 
     * given (shared memory, sockets, etc). I don't know anything 
     * about what type of connection is established only that all 
     * communication is handled by the wait_For_Jobs and generate_Jobs functions 
     */ 
     start_Server(client_pid, connection_type); 
     wait_For_Jobs(); 
    } else { 
     // gets information needed to send messages to server 
     contact_info = wait_for_connection(); 
     generate_Jobs(contact_info); 
    } 
} 

Dies ist eine sehr, sehr groben Umriss von dem, was ich will. Die Frage, die ich habe, hängt mit der Funktion "wait_For_Jobs" zusammen. Unglücklicherweise wird der connection_type erst zur Laufzeit bekannt sein und daher kann diese Frage mehrere verschiedene Antworten haben, abhängig davon, welche Art von Kommunikationsmethode verwendet wird (dh Shared Memory, Sockets, etc.). Der Einfachheit halber wird angenommen, dass Shared Memory der verwendete Kommunikationstyp ist (sprich Boost-Interprozess). In diesem Sinne, was ist der beste und effizienteste Weg für den Server auf Eingaben vom Client zu warten? Ein möglicher Ansatz besteht darin, eine while-Schleife in der unten angegebenen Weise zu verwenden.

void wait_For_Jobs() { 
    while(true) { 
     if(check_If_Message_Received_Over_Shared_Memory){ 
      // handle message 
     } 
    } 
} 

Ich vermute jedoch, dass dies sehr ineffizient sein wird; der Prozess dreht immer "seine Räder". Etwas von einer Lösung wäre es, den Prozess am Ende der while-Schleife für eine gewisse Zeit zu "schlafen". Das ist nicht wirklich anders als nur den Code in der while-Schleife auszuführen (in der Tat ist es das gleiche); Es verringert nur die Ressourcennutzung auf Kosten der Reaktionszeit. Idealerweise sollte sich der Prozess nur in einem Standby-Modus befinden und nach dem Empfang einer Nachricht mit der Berechnung beginnen. Ich bin mir jedoch nicht sicher, wie Sie so etwas in C oder Cpp machen würden. Gibt es dafür eine bessere Alternative?

+0

* "es ist möglich, dass der Client und der Server zwei verschiedene Maschinen sind" * - das schließt den gemeinsamen Speicher eher aus, ich würde in Bezug auf Sockets denken. – Galik

+0

Es gibt eine if-Anweisung, die zur Laufzeit festlegt, wie die Dinge laufen. Auf diese Weise können Benutzer bestimmen, ob sie lokal ausgeführt werden sollen (vorausgesetzt, die Hardwarebenutzer verfügen über). Der Kernpunkt dieser Frage ist, ob es möglich ist, die Forschungsnutzung (dh die CPU-Nutzung) zu verringern, indem keine While-Schleife verwendet wird, wie oben in der Frage erwähnt. Selbst wenn zum Beispiel ein Semaphor verwendet wird, vermute ich, dass irgendwo im kompilierten Code eine while-Schleife existiert. Die Frage ist, ob diese Schleife effizienter ist. In einem System wie Android kann das Betriebssystem einen Prozess in den Ruhezustand versetzen und ihn wecken, wenn eine Nachricht an ihn gesendet wird. – Ryan

+0

Wenn in C/CPP etwas Ähnliches getan werden kann (statt dies standardmäßig zu tun, kann ein Programm ein Betriebssystem anfordern) etwas Ähnliches) dann denke ich, es wäre viel effizienter als ein Semaphor. In der Tat werden Semaphore meines Wissens hauptsächlich für die Ressourcenverwaltung und -zuweisung verwendet; nicht die Auslastung zu reduzieren. – Ryan

Antwort

0

Wenn Sie Shared Memory verwenden, müssen Sie auf einem Semaphor blockieren, der ausgelöst wird, wenn eine andere Anfrage erscheint.

Wenn Sie Sockets verwenden, verwenden Sie einen blockierenden Empfang.

+0

Ja, aber müssten Sie nicht ständig das Semaphor überprüfen? Das ist konzeptionell nicht dasselbe wie das Ausführen einer while-Schleife (in Bezug auf die Ressourcennutzung)? Und das gleiche für die Sperrung erhalten. Genauer gesagt, wenn ich einen Semaphor blockiere, wird eine while-Schleife im eigentlichen Code, den ich schreibe, nicht benötigt (zumindest denke ich nicht, ich bin nicht mit Semaphoren in C/Cpp vertraut) Um zu überprüfen, ob der Prozess noch blockiert ist, vermute ich, dass es irgendwo eine While-Schleife geben muss, nachdem der Code kompiliert wurde – Ryan

+0

Ich denke, eine andere Art, diese Frage zu stellen, ist eine Leistungssteigerung durch Verwendung eines Semaphors oder Blockierens empfangen? – Ryan

+0

Nein Semaphore und Blockierung liest Block * im Kernel * und werden durch Ereignisse aufgeweckt. Keine Spin-Schleife.Re Ihre letzte Frage, "Leistungssteigerung" im Vergleich zu was? – EJP