C 如何编写测试用例来验证linux中sem_wait函数返回的EINTR
我刚刚编写了下面的例程来处理EINTR错误。 程序如下所示:C 如何编写测试用例来验证linux中sem_wait函数返回的EINTR,c,linux,semaphore,C,Linux,Semaphore,我刚刚编写了下面的例程来处理EINTR错误。 程序如下所示: while((s = sem_wait(&w4compl)) == -1) { if (errno == EINTR) { perror("call interrupted by sig. handler\n"); continue; } else printf("Ot
while((s = sem_wait(&w4compl)) == -1)
{
if (errno == EINTR)
{
perror("call interrupted by sig. handler\n");
continue;
}
else
printf("Other Error Generated\n");
}
因此,在这里我无法看到print“callinterrupted by sig.handler\n”语句。如何测试它以使其打印相同的内容(如何执行if(errno==EINTR)部分)。如果系统调用被中断,Linux上几乎任何系统调用都可以返回
EINTR
从(我的)重点:
sem\u wait()
减少(锁定)由sem
指向的信号量。如果
信号量的值大于零,则减量
继续,函数立即返回。如果信号量
当前值为零,则调用阻塞,直到
可以执行减量(即信号量值
高于零),或信号处理程序中断调用
要触发这种情况,您应该确保sem_wait
系统调用被阻止(等待),然后向线程发送信号(具有处理程序)
一些psuedo代码:
sigint_handler:
return
thread2:
<Your while loop from the question>
main:
signal(SIGINT, sigint_handler) // Setup signal handler
sem_wait(&w4compl)
t2 = start_thread(thread2)
sleep(5) // Hack to make sure thread2 is blocked
pthread_kill(t2, SIGINT)
sigint\u处理程序:
返回
线程2:
主要内容:
信号(SIGINT,SIGINT\u处理程序)//设置信号处理程序
sem_wait(&w4compl)
t2=起始螺纹(螺纹2)
sleep(5)//进行黑客攻击以确保thread2被阻止
pthread_kill(t2,SIGINT)
安装一个信号处理程序,并发送一个信号(使用报警()
,设置定时器()
,或定时器创建()
+定时器设置时间()
),这样信号的发送将中断sem\u等待()
调用
考虑以下示例程序:
#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;
}
程序将输出
一秒钟后。嗨,p.p.如果这个问题已经回答了,你能给我链接吗?它在你的问题中是链接的。@p.p.如果你仔细看,那实际上不是一个好的副本。当然,标题很好,也很一般,但最重要的答案都是“不要重新调用
fclose()
”,这在这里并没有真正的帮助。同意乔纳森的观点。这对我帮助不大。@JonathonReinhart链接的问题是针对单元测试EINTR的,OP在这里也问了这个问题。这里有不错的答案。当然,fclose就是一个例子(这里是sem_的帖子)。我不确定每个可能返回EINTR的系统调用都需要一个不同的问题,以及如何对其进行单元测试。谢谢@Jonathan Reinhart。这里的例程调用了一个线程。那个么我怎样才能给线程一个SIGINT信号呢?用来给线程发送一个信号。为了理解,OP应该在这里阻止哪个系统调用?为什么是SIGINT?@Jonathan我将在现有代码中尝试伪代码并检查。1。使用信号
不是一个好主意(最好使用sigaction)。2.除了作为同步机制的sleep
是一个糟糕的选择之外,sleep
本身也可能会被信号中断(我仍然不明白sleep
在main中是如何确保它在线程中被阻塞的)。@NiravPatel:请注意,如果有多个线程,信号必须指向执行sem\u wait()的线程
调用,并且导致阻塞调用中断的是向用户空间处理函数传递信号,而不是信号本身。在某些情况下,您可能需要一个信号对,主信号在除一个线程外的所有线程中都被阻塞,以便其信号处理程序可以将信号(使用未阻塞的辅助信号)“转发”到每个现有的其他线程,以中断多个线程。如果您需要更多详细信息或示例,请告诉我。
gcc -Wall -O2 example.c -lpthread -o example
./example
sem_wait() failed with errno == EINTR (4; Interrupted system call).