Избегайте многопроцессного и многопоточного программирования, если можете. Эта дорога ведет к боли. Используйте управляемое событиями программирование. Для того типа вещей, которые вы хотите сделать, программирование на основе событий намного проще и будет работать точно так же. В C два основных способа выполнения событийно-ориентированного программирования (связанные с вводом / выводом) - select
и poll
.
Вот рабочий пример использования select:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
int
main(void)
{
fd_set rfds;
struct timeval tv;
int retval, len;
char buf[4096];
while (1) {
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
if (retval == -1) {
perror("select()");
exit(EIO);
} else if (retval) {
printf("Data is available now.\n");
} else {
printf("No data within five seconds.\n");
continue;
}
if (FD_ISSET(0, &rfds)) {
len = read(0, buf, 4096);
if (len > 0) {
buf[len] = 0;
printf("Got data on stdin: %s\n", buf);
} else {
// fd closed
perror("read()");
exit(EIO);
}
}
}
}
FD_SET используется для создания списка файлов-дескрипторов, по которым вы хотите выбрать (получить события). После успешного возврата select (то есть обработки события) вы используете FD_ISSET, чтобы найти файловые дескрипторы, которые вызвали события. В вашем случае у вас будет файл-дескриптор с открытым сокетом, который вы добавите в набор и обработаете соответствующим образом.
Полезная документация включает следующие справочные страницы:
man 2 select
man 2 poll
man 3 read
man 3 open