首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OS上的AIO与Linux上的AIO--为什么它不能在MacOSX10.6上工作

OS上的AIO与Linux上的AIO--为什么它不能在MacOSX10.6上工作
EN

Stack Overflow用户
提问于 2010-02-06 03:52:46
回答 4查看 4K关注 0票数 5

我的问题真的很简单。下面的代码为什么在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,这仅仅意味着“资源暂时不可用”。为什么会这样呢?

代码语言:javascript
复制
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。令人扫兴!

EN

回答 4

Stack Overflow用户

发布于 2013-01-28 03:53:24

本文给出的代码在山狮10.8.2上进行了测试。它适用于一个小的修正。线

代码语言:javascript
复制
 "aio->aio\_fildes = sd;"

例如,应将其改为:

代码语言:javascript
复制
  aio->aio\_fildes = open( "/dev/null", O\_RDWR);

得到预期的结果。

看手册。“aio_write()函数允许调用进程对先前打开的文件执行异步写入。”

票数 2
EN

Stack Overflow用户

发布于 2010-02-17 22:59:42

我的代码非常类似于您在10.6.2上的代码(但编写到一个文件中),没有任何问题--所以可以做您正在尝试的事情。

出于好奇,您对SIGIO常量使用的值是什么?我发现在OS中有一个无效的值会导致aio_write失败,所以我总是传递SIGUSR1。

也许可以检查sigaction()的返回值以验证信号细节?

票数 1
EN

Stack Overflow用户

发布于 2010-02-18 21:50:16

链接中提出的要点都指向了一种不同的方法来引发io完成通知(例如,kqueue是一种特定于BSD的机制),但并没有真正回答您关于异步io的重新POSIX方法的问题。以及他们是否在达尔文工作。

UNIX世界确实是这方面的解决方案的混搭,如果有一个尝试过和测试过的解决方案在所有平台上都能工作,唉,目前还没有- POSIX是最具一致性的解决方案,那就太好了。

在黑暗中有点刺痛,但在套接字句柄上设置非阻塞(即set套接字选项O_NONBLOCK )以及使用SIGUSR1也可能是有用的

如果我有时间,我会处理你的套接字样本,看看我是否也能从中得到任何东西。

祝你好运。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2211951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档