gpt4 book ai didi

C - 如何同时使用 aio_read() 和 aio_write()

转载 作者:太空狗 更新时间:2023-10-29 14:53:36 24 4
gpt4 key购买 nike

我实现了需要读写的游戏服务器。所以我接受传入连接并使用 aio_read() 开始读取它,但是当我需要发送一些东西时,我停止使用 aio_cancel() 读取然后使用 aio_write () 。在 write 的回调中,我继续阅读。所以,我确实一直在读书,但当我需要发送一些东西时 - 我暂停阅读。

它在大约 20% 的时间内工作 - 在其他情况下调用 aio_cancel() 失败并显示“操作正在进行中” - 我无法取消它(即使在永久 while 周期)。所以,我添加的写操作永远不会发生。

如何用好这些功能?我错过了什么?

编辑:在 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(...);
}
}

最佳答案

如果您希望为读取和写入设置单独的 AIO 队列,以便稍后发出的写入可以在较早发出的读取之前执行,那么您可以使用 dup() 创建一个副本套接字,并使用一个发出读取,另一个发出写入。

但是,我支持完全避免 AIO 的建议,并简单地使用 epoll() 驱动的事件循环和非阻塞套接字。这种技术已被证明可以扩展到大量客户端——如果你的 CPU 使用率很高,分析它并找出它发生的位置,因为很可能不是你的事件循环才是罪魁祸首.

关于C - 如何同时使用 aio_read() 和 aio_write(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6497217/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com