我的问题真的很简单。下面的代码为什么在Linux上工作,而在MacOSX10.6.2雪豹上却不能工作。
要将文件编译为aio.cc,并在Linux上使用g++ aio.cc -o aio -lrt进行编译,在Mac上使用g++ aio.cc -o aio进行编译。我在Mac上使用MacOSX10.6.2,在Linux上使用Linux2.6进行测试。
我在OS上看到的失败是aio_write在-1中失败,并将errno设置为EAGAIN,这仅仅意味着“资源暂时不可用”。为什么会这样呢?
extern "C" {
#include <aio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <signal.h>
}
#include <cassert>
#include <string>
#include <iostream>
using namespace std;
static void
aio_completion_handler(int signo, siginfo_t *info, void *context)
{
using namespace std;
cout << "BLAH" << endl;
}
int main()
{
int err;
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_port = htons(1234);
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_family = PF_INET;
int sd = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sd == -1) {
assert(!"socket() failed");
}
const struct sockaddr *saddr = reinterpret_cast<const struct sockaddr *>(&sin);
err = ::connect(sd, saddr, sizeof(struct sockaddr));
if (err == -1) {
perror(NULL);
assert(!"connect() failed");
}
struct aiocb *aio = new aiocb();
memset(aio, 0, sizeof(struct aiocb));
char *buf = new char[3];
buf[0] = 'a';
buf[1] = 'b';
buf[2] = 'c';
aio->aio_fildes = sd;
aio->aio_buf = buf;
aio->aio_nbytes = 3;
aio->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
aio->aio_sigevent.sigev_signo = SIGIO;
aio->aio_sigevent.sigev_value.sival_ptr = &aio;
struct sigaction sig_act;
sigemptyset(&sig_act.sa_mask);
sig_act.sa_flags = SA_SIGINFO;
sig_act.sa_sigaction = aio_completion_handler;
sigaction(SIGIO, &sig_act, NULL);
errno = 0;
int ret = aio_write(aio);
if (ret == -1) {
perror(NULL);
}
assert(ret != -1);
}UPDATE (2010年2月):OSX根本不支持套接字上的AIO。令人扫兴!
发布于 2013-01-28 03:53:24
本文给出的代码在山狮10.8.2上进行了测试。它适用于一个小的修正。线
"aio->aio\_fildes = sd;"例如,应将其改为:
aio->aio\_fildes = open( "/dev/null", O\_RDWR);得到预期的结果。
看手册。“aio_write()函数允许调用进程对先前打开的文件执行异步写入。”
发布于 2010-02-17 22:59:42
我的代码非常类似于您在10.6.2上的代码(但编写到一个文件中),没有任何问题--所以可以做您正在尝试的事情。
出于好奇,您对SIGIO常量使用的值是什么?我发现在OS中有一个无效的值会导致aio_write失败,所以我总是传递SIGUSR1。
也许可以检查sigaction()的返回值以验证信号细节?
发布于 2010-02-18 21:50:16
链接中提出的要点都指向了一种不同的方法来引发io完成通知(例如,kqueue是一种特定于BSD的机制),但并没有真正回答您关于异步io的重新POSIX方法的问题。以及他们是否在达尔文工作。
UNIX世界确实是这方面的解决方案的混搭,如果有一个尝试过和测试过的解决方案在所有平台上都能工作,唉,目前还没有- POSIX是最具一致性的解决方案,那就太好了。
在黑暗中有点刺痛,但在套接字句柄上设置非阻塞(即set套接字选项O_NONBLOCK )以及使用SIGUSR1也可能是有用的
如果我有时间,我会处理你的套接字样本,看看我是否也能从中得到任何东西。
祝你好运。
https://stackoverflow.com/questions/2211951
复制相似问题