3

我试图用信号(SIGUSR1)中断readline,但显然如果信号没有被处理,程序就会退出,在处理时,它会继续readline,就好像什么都没发生一样。readline 是否应该能够使用信号中断。

我从另一个问题中得到了这个想法:force exit from readline() function

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <readline/readline.h>
#include <pthread.h>

pthread_t main_id;

void *thread_main(void* arg)
{
  sleep(10);
  pthread_kill(main_id, SIGUSR1);
}

void signal_handler(int sig)
{
  puts("got signal");
  (void) sig;
}

int main(int argc, char** argv)
{
  struct sigaction sa;
  sa.sa_handler = signal_handler;
  sa.sa_flags = 0;
  sigemptyset(&sa.sa_mask);
  sigaction(SIGUSR1, &sa, NULL);

  main_id = pthread_self();

  pthread_t id;
  pthread_create(&id, NULL, thread_main, NULL);

  char *input = readline("prompt> ");

  puts("main thread done");
  return 0;
}

输出:

$ ./test
prompt> got signal
enter something
main thread done
$

谢谢。

4

3 回答 3

2

Joachim Pileborg 在评论中回答了这个问题。

最好的解决方案似乎是使用 readline 备用接口。文档位于http://www.delorie.com/gnu/docs/readline/rlman_41.html

在http://www.mcld.co.uk/blog/blog.php?274也是一个非常基本的例子,只需要适应使用 select 而不是使用 sleep 轮询。

比使用信号好多了!

于 2012-09-07T22:23:43.800 回答
1

改变你的signal_handler功能:

void signal_handler(int sig)
{
        puts("got signal");
        //(void) sig;
        exit(sig);
}
于 2012-09-06T00:31:06.300 回答
1

libreadline读取字符 ( ) 的默认实现int rl_getc(FILE *)确实以简单的方式处理EINTR(由read()if signalled 返回)read()。由于这个接收信号不会取消readline()

要解决此问题,您可以将函数指针设置rl_getc_function为您自己的实现以读取字符(默认rl_getc_function指向rl_getc())。

于 2012-09-06T12:27:56.780 回答