Допустим, у меня есть две библиотеки (A и B), и в каждой есть одна функция, которая слушает сокеты. Эти функции используют select() и немедленно возвращают какое-то событие, если данные поступили, в противном случае они ждут некоторое время (timeout), а затем возвращают NULL:
A_event_t* A_wait_for_event(int timeout);
B_event_t* B_wait_for_event(int timeout);
Теперь я использую их в своей программе:
int main (int argc, char *argv[]) {
// Init A
// Init B
// .. do some other initialization
A_event_t *evA;
B_event_t *evB;
for(;;) {
evA = A_wait_for_event(50);
evB = B_wait_for_event(50);
// do some work based on events
}
}
Каждая библиотека имеет свои собственные сокеты (например, сокет udp) и недоступна извне.
ПРОБЛЕМА: это не очень эффективно. Если, например, есть много событий, ожидающих доставки с помощью *B_wait_for_event*, им придется всегда ждать, пока не истечет время ожидания *A_wait_for_event*, что эффективно ограничивает пропускную способность библиотеки B и моей программы.
Обычно можно использовать потоки для разделения обработки, НО что, если обработка некоторого события требует вызова функции другой библиотеки и наоборот. Пример:
if (evA != 0 && evA == A_EVENT_1) {
B_do_something();
}
if (evB != 0 && evB == B_EVENT_C) {
A_do_something();
}
Таким образом, даже если бы я мог создать два потока и отделить функциональность от библиотек, эти потоки должны были бы обмениваться событиями между собой (вероятно, через канал). Это по-прежнему будет ограничивать производительность, потому что один поток будет заблокирован функцией *X_wait_for_event()*, и будет невозможно немедленно получить данные из другого потока.
Как это решить?