Я реализую игровой сервер, где мне нужно читать и писать. Поэтому я принимаю входящее соединение и начинаю читать с него, используя aio_read(), но когда мне нужно что-то отправить, я перестаю читать, используя aio_cancel(), а затем используйте aio_write(). В обратном вызове записи я возобновляю чтение. Итак, я все время читаю, но когда мне нужно что-то отправить - я пауза чтение.C - Как использовать оба aio_read() и aio_write()
Он работает на ~ 20% времени - в другом случае вызова aio_cancel() терпит неудачу с «Операция в настоящее время в процессе» - и я не могу отменить его (даже в пределах постоянного в то время как цикла). Таким образом, моя добавленная операция записи никогда не происходит.
Как хорошо использовать эти функции? Что я пропустил?
EDIT: Используется под Linux 2.6.35. Ubuntu 10 - 32 бит.
Пример кода:
void handle_read(union sigval sigev_value) { /* handle data or disconnection */ }
void handle_write(union sigval sigev_value) { /* free writing buffer memory */ }
void start()
{
const int acceptorSocket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
bind(acceptorSocket, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
listen(acceptorSocket, SOMAXCONN);
struct sockaddr_in address;
socklen_t addressLen = sizeof(struct sockaddr_in);
for(;;)
{
const int incomingSocket = accept(acceptorSocket, (struct sockaddr*)&address, &addressLen);
if(incomingSocket == -1)
{ /* handle error ... */}
else
{
//say socket to append outcoming messages at writing:
const int currentFlags = fcntl(incomingSocket, F_GETFL, 0);
if(currentFlags < 0) { /* handle error ... */ }
if(fcntl(incomingSocket, F_SETFL, currentFlags | O_APPEND) == -1) { /* handle another error ... */ }
//start reading:
struct aiocb* readingAiocb = new struct aiocb;
memset(readingAiocb, 0, sizeof(struct aiocb));
readingAiocb->aio_nbytes = MY_SOME_BUFFER_SIZE;
readingAiocb->aio_fildes = socketDesc;
readingAiocb->aio_buf = mySomeReadBuffer;
readingAiocb->aio_sigevent.sigev_notify = SIGEV_THREAD;
readingAiocb->aio_sigevent.sigev_value.sival_ptr = (void*)mySomeData;
readingAiocb->aio_sigevent.sigev_notify_function = handle_read;
if(aio_read(readingAiocb) != 0) { /* handle error ... */ }
}
}
}
//called at any time from server side:
send(void* data, const size_t dataLength)
{
//... some thread-safety precautions not needed here ...
const int cancellingResult = aio_cancel(socketDesc, readingAiocb);
if(cancellingResult != AIO_CANCELED)
{
//this one happens ~80% of the time - embracing previous call to permanent while cycle does not help:
if(cancellingResult == AIO_NOTCANCELED)
{
puts(strerror(aio_return(readingAiocb))); // "Operation now in progress"
/* don't know what to do... */
}
}
//otherwise it's okay to send:
else
{
aio_write(...);
}
}
Вы должны указать, какая ОС это. Также попробуйте создать минимальный автономный пример, который показывает проблему. В противном случае, вы уверены, что вам нужно отменить его? Я думаю, что вполне нормально, что операции чтения и записи ожидаются в одном дескрипторе файла. –
В C++ я использую два потока для работы в одном и том же сокете одновременно. Один читатель, один писатель. Я думаю, что это могло бы работать и с айо, но я не уверен, но, возможно, это может ответить кому-то. –
Не могли бы вы объяснить, _why_ вам нужно приостановить чтение? Не разрешает ли aio выдавать запрос на запись без отмены чтения? –