| Autor |
Nachricht |
Linuxer
Unregistrierter
|
Linuxer Unregistrierter
20:24:12 30.08.2010 Titel: |
recv() beenden |
Zitieren |
Hi,
Ich haben ein Server-Programm geschrieben (multithreaded) und habe jetzt folgendes Problem:
mein Listen-Thread sieht in etwa so aus:
| C/C++ Code: | 1 2 3 4 5 6 7 8 9 10 | 1 2 3 4 5 6 7 8 9 10 | while(!shutdown)
{
char msg[BUFFERSIZE];
int status = recv(socket_fd, msg, sizeof(msg),0 ); // read message from client
if(status <= 0) // client closed transmission or an error occured
{
//error-handling
}
} | |
| C/C++ Code: | 1 2 3 4 5 6 7 8 9 10 | while(!shutdown)
{
char msg[BUFFERSIZE];
int status = recv(socket_fd, msg, sizeof(msg),0 ); // read message from client
if(status <= 0) // client closed transmission or an error occured
{
//error-handling
}
} | |
| C/C++ Code: | 1 2 3 4 5 6 7 8 9 10 | while(!shutdown)
{
char msg[BUFFERSIZE];
int status = recv(socket_fd, msg, sizeof(msg),0 ); // read message from client
if(status <= 0) // client closed transmission or an error occured
{
//error-handling
}
} | |
nun möchte ich mit der Variable shutdown den Thread enden lassen, allerdings bleibt der immer beim recv hängen (was auch klar ist). Wie löse ich das am besten?
Ein Timeout ist die letzte Wahl und mMn nicht sinvoll wenn ich 1sec oder länger darauf warten muss nachdem die Variable geändert wurde. Wenn ich die Zeit verkürze muss ich ständig ein keepalive-Signal senden was mir auch nicht wirklich gefällt.
LG |
|
|
|
 |
rüdiger
Moderator
Benutzerprofil
Anmeldungsdatum: 11.07.2001
Beiträge: 22629
|
rüdiger Moderator
21:20:03 30.08.2010 Titel: |
|
Zitieren |
Das Socket auf Nonblocking setzen.
| C/C++ Code: | 1 2 3 4 5 6 7 8 | 1 2 3 4 5 6 7 8 | int flags = fcntl(fd, F_GETFL, 0);
if(flags == -1) {
flags = 0;
}
if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror("fcntl");
// ...
}
| |
| C/C++ Code: | 1 2 3 4 5 6 7 8 | int flags = fcntl(fd, F_GETFL, 0);
if(flags == -1) {
flags = 0;
}
if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror("fcntl");
// ...
}
| |
| C/C++ Code: | 1 2 3 4 5 6 7 8 | int flags = fcntl(fd, F_GETFL, 0);
if(flags == -1) {
flags = 0;
}
if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror("fcntl");
// ...
}
| |
fcntl(2) |
|
|
|
 |
Linuxer
Unregistrierter
|
Linuxer Unregistrierter
13:56:37 31.08.2010 Titel: |
|
Zitieren |
Daran habe ich auch gedacht, allerdings habe ich dann eine CPU-Auslastung von 90-100% was alles andere als gut ist.
LG |
|
|
|
 |
LeMacabre
Unregistrierter
|
LeMacabre Unregistrierter
15:27:43 31.08.2010 Titel: |
|
Zitieren |
Schläfer doch dein Programm für n Millisekunden ein.
Sollte somit die Auslastung verbessern.
Wird das nicht sonst auch so gehandhabt? |
|
|
|
 |
Linuxer
Unregistrierter
|
Linuxer Unregistrierter
15:40:54 31.08.2010 Titel: |
|
Zitieren |
Sowas wie sleep(1) geht bei mir vielleicht als Hack durch, aber bestimmt nicht als saubere Lösung.
Ich kann mir nicht ganz vorstellen das man das so macht...
LG |
|
|
|
 |
TyRoXx
Mitglied
Benutzerprofil
Anmeldungsdatum: 30.06.2009
Beiträge: 623
|
TyRoXx Mitglied
16:45:26 31.08.2010 Titel: |
|
Zitieren |
select oder epoll |
_________________ Das dynamische Array heißt in C++ std::vector, das statische std::array. Nur PI weiß es wieder besser.
|
|
 |
rüdiger
Moderator
Benutzerprofil
Anmeldungsdatum: 11.07.2001
Beiträge: 22629
|
rüdiger Moderator
16:46:17 31.08.2010 Titel: |
|
Zitieren |
Setzt du shutdown in einem anderen Thread? Dann ist eine ungeschützte Abfrage ohnehin nicht sicher. Aber du könntest das Problem lösen, wenn du anstelle shutdown einfach eine pipe nimmst und dann zB mit epoll auf die pipe und das socket wartest. Wenn etwas auf dem socket kommt, dann kannst du einfach read aufrufen und wenn etwas bei shutdown kommt, dann machst du eben ein shutdown. |
|
|
|
 |
2.6.22
Unregistrierter
|
2.6.22 Unregistrierter
17:21:38 31.08.2010 Titel: |
|
Zitieren |
| Zitat: | | Applications can use an eventfd file descriptor instead of a pipe (see pipe(2)) in all cases where a pipe is used simply to signal events. The kernel overhead of an eventfd file descriptor is much lower than that of a pipe, and only one file descriptor is required (versus the two required for a pipe). | |
|
|
|
 |
Linuxer
Unregistrierter
|
Linuxer Unregistrierter
19:17:53 31.08.2010 Titel: |
|
Zitieren |
Danke,
genau sowas habe ich gesucht.
LG |
|
|
|
 |
rüdiger
Moderator
Benutzerprofil
Anmeldungsdatum: 11.07.2001
Beiträge: 22629
|
rüdiger Moderator
20:36:23 31.08.2010 Titel: |
|
Zitieren |
| 2.6.22 schrieb: | | Zitat: | | Applications can use an eventfd file descriptor instead of a pipe (see pipe(2)) in all cases where a pipe is used simply to signal events. The kernel overhead of an eventfd file descriptor is much lower than that of a pipe, and only one file descriptor is required (versus the two required for a pipe). |
|
Oh danke. Man lernt immer was dazu.
eventfd(2) |
|
|
|
 |