3

シグナル (SIGUSR1) で readline を中断しようとしていますが、明らかにシグナルが処理されない場合、プログラムは終了し、処理時に readline は何も起こらなかったかのように進行します。readline は、シグナルを使用して中断できるはずです。

私はこの他の質問からアイデアを得ました: readline() 関数からの強制終了

#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の非常に基本的な例も、スリープでポーリングする代わりに選択を使用するように適応させる必要があります。

信号を使用するよりもはるかに優れています。

于 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文字を読み取る のデフォルトの実装 ( ) は、単に re- ing する方法でint rl_getc(FILE *)処理します (通知された場合EINTRに返されます)。このため、信号を受信して​​もキャンセルされませread()read()readline()

これを回避するには、関数ポインターrl_getc_functionを独自の実装に設定して、文字を読み取ることができます (デフォルトでrl_getc_functionは を指しrl_getc()ます)。

于 2012-09-06T12:27:56.780 に答える