我刚刚编写了下面的例程来处理EINTR错误。
程序如下所示,

while((s = sem_wait(&w4compl)) == -1)
{
        if (errno == EINTR)
        {
                perror("call interrupted by sig. handler\n");
                continue;
        }
        else
                printf("Other Error Generated\n");
}

所以,这里我看不到打印的“被sig打断的呼叫”。处理程序语句。如何测试它以使其打印相同的内容(如何执行if(errno==EINTR)的部分)。

最佳答案

安装一个信号处理程序,并发送信号(使用alarm()setitimer()timer_create()+timer_settime()),这样信号的发送将中断sem_wait()调用。
考虑这个示例程序:

#define  _POSIX_C_SOURCE  200809L
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>

static void dummy_handler(int signum)
{
}

static int install_dummy_handler(int signum)
{
    struct sigaction  act;
    memset(&act, 0, sizeof act);
    sigemptyset(&act.sa_mask);
    act.sa_handler = dummy_handler;
    act.sa_flags = 0;
    return sigaction(signum, &act, NULL);
}

static const char *errname(const int errnum)
{
    switch (errnum) {
    case EINTR:  return "EINTR";
    case EINVAL: return "EINVAL";
    default:     return "(other)";
    }
}

int main(void)
{
    sem_t  s;

    if (install_dummy_handler(SIGALRM) == -1) {
        fprintf(stderr, "Cannot install ARLM signal handler: %s.\n", strerror(errno));
        return EXIT_FAILURE;
    }

    sem_init(&s, 0, 0);

    alarm(1);

    if (sem_wait(&s) == -1) {
        const int  errnum = errno;
        printf("sem_wait() failed with errno == %s (%d; %s).\n",
               errname(errnum), errnum, strerror(errnum));
    } else
        printf("sem_wait() succeeded.\n");

    return EXIT_SUCCESS;
}

main()中,我们为SIGALRM信号安装一个信号处理程序。信号处理函数是否执行任何操作都无关紧要,因为正是信号的传递导致“慢速”系统调用返回EINTR错误。(只要在安装该处理程序时未使用SA_RESTART标志。如果您查看act.sa_mask中的install_dummy_handler(),您将看到我们根本没有使用标志。sigaction()手册页中介绍了所有标志和man 2 sigaction用法。)
main()中,我们首先初始化信号量,然后设置一秒钟的警报。当实际的挂钟时间过去后,信号就会上升。
请注意,尽管SIGALRM对于本例和类似的目的来说很好,但是您可能需要使用POSIX per-process interval timers
接下来,我们只需对信号量调用sem_wait(),并检查结果。实际上,如果您使用例如。
gcc -Wall -O2 example.c -lpthread -o example
./example

程序将输出
sem_wait() failed with errno == EINTR (4; Interrupted system call).

一秒钟后。

关于c - 如何编写测试用例以验证Linux中sem_wait函数返回的EINTR,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51725823/

10-11 23:12