我刚刚编写了下面的例程来处理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/