【问题标题】:Setting standard signal SIGIO in GNU在 GNU 中设置标准信号 SIGIO
【发布时间】:2017-06-14 11:29:53
【问题描述】:

我发现 GNU 库中记录了 SIGIO 信号。据说只要我有输入(特别是在套接字中),系统就有可能发送信号。 根据创建此类信号的文档,我应该将 O_ASYNC 标志设置为相应的文件描述符。 我的问题是我的 GNU 版本(gcc 6.3.0)无法识别这样的关键字:

错误:'O_ASYNC' 未声明(在此函数中首次使用)

我使用以下块设置标志:

/* Set socket status async */
int status = fcntl(sockfd, F_SETFL, O_ASYNC);;
if (status < 0) error("Can't set async mode");
else printf("Async is set for signal %d\n", SIGIO); 

我使用 Cigwin GCC 6.3.0

代码如下:

static void OnTimer(int sig)
{
   /* write request to socket BIO */
}
static void OnTick(int sig)
{
   char read[BUFSIZE] = {};
   int received;

    received = SSL_read(ssl, read, sizeof(read));
    /* Handle errors here */
    /* print the server's reply */
    printf("%s\n\n", read);
}

void connectSSL()
{
    /* do all socket set-up and connection */

    /* Establish handler for I/O signal */
    saction.sa_flags = 0;
    saction.sa_handler = OnTick;
    sigemptyset(&saction.sa_mask);
    sigaddset(&saction.sa_mask, SIGALRM);
    if (sigaction(SIGIO, &saction, NULL) == -1) error("sigaction");
    else printf("OnTick handler created\n");

    /* Set socket status async */
    int status = fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | FASYNC);
    if (status < 0) error("Can't set async mode");
    else printf("Async is set for signal %d\n", SIGIO);

    /* Select the process to receive the signal */
    int process = fcntl(sockfd, F_SETOWN, getpid());
    if (process < 0) error("Can't set address process");
    else printf("Process %d is set\n", getpid());

    /* do the rest SSL staff here */
}

int main(int argc, char argv[])
{
    sigset_t mask, oldmask;
    /* Wait for OnTimer event*/
    sigemptyset(&oldmask);
    sigaddset(&oldmask, SIGALRM);
    sigemptyset(&mask);
    sigaddset(&mask, SIGALRM);
    sigaddset(&mask, SIGIO);
    sigprocmask(SIG_BLOCK, &mask, &oldmask);
    connectSSL();
    createTimer(500000000);
    while(1)
    {
        printf("\nWaiting OnTimer %d\n", count + 1);
        sigsuspend(&oldmask);
    }

    return 0;
}

【问题讨论】:

  • 除了我在下面的实际答案之外:根据我的经验,信号控制 I/O 带来的问题比它实际解决的问题要多。一旦您通过信号处理程序了解了您可能实际做什么(为您的操作系统查找“异步安全功能”),您可能希望将您的设计恢复为select 之类的东西。
  • 也许你是对的。我还是想试试。目前我根本无法设置此信号。
  • 我对 select 不完全满意的一个原因是 select 在 socket 中有真正的输入消息之前被调用了 4 次。我想 select 会不断轮询所有 I/O 描述符,并在所有其他 fd 准备好时恢复 1。我需要更快的解决方案。

标签: c io signals gnu


【解决方案1】:

很可能您忘记包含sys/fcntl.h,无论是间接还是直接。这是定义标志的地方。

如果未定义O_ASYNC,您可以尝试使用该标志的功能等效前身FASYNC

还要确保你已经执行了一个

int flags;

/* Install signal handler here... */

/* Set flags to receive SIGIO (and SIGURG) signals */
flags = fcntl (F_GETFL, 0);
flags = fcntl (F_SETFL, flags | FASYNC);

/* Bind our process as receiver of SIGIO signals */
flags = fcntl (F_SETOWN, getpid ());

【讨论】:

  • 我已经包含了 fcntl.h,它用于 O_NONBLOCK 状态标志。我检查了 fcntl.h、sys/fcntl.h 和 _default_fcntl.h 的所有三个文件。没有提到像 O_ASYNC 这样的宏。
  • 你能用FASINC代替吗?那应该是功能等效的前身。
  • FASYNC 我是想写
  • gcc 识别并编译文件。但信号仍然不起作用。
  • 在这种情况下,您需要发布更多代码,尤其是关于如何安装信号处理程序的代码。你有没有用 F_SETOWN 告诉系统通知哪个进程?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 2013-09-19
  • 2013-10-05
  • 1970-01-01
相关资源
最近更新 更多