2017-01-21 49 views
2

我的第一篇文章,很抱歉,如果不符合规则。 需要在C问题的建议。是否可以更改信号处理程序返回点?

我正在使用信号处理程序(SIGALRM)与用户(Stdin)的输入超时。 如果用户没有输入任何内容,那么:

  1. 超时过期

  2. 信号处理函数中调用

  3. (的问题) - >返回到同一线路发生超时之前。

重要: 我不能使用select和因为它是一个第三方机制,我使用,必须使用他们的方法不能使用轮询功能。 他们最终使用select,但它不是直接的,我只需要使用他们的方法。

问题是: 从信号处理程序返回后,我仍然'卡在'等待输入的同一行 我不能使用longjmp,不能调用其他方法,不能打印消息到用户不能使用goto 所有不安全的处理而产生错误

代码看起来是这样的:。

sa.sigaction(SIGALRM, &handler,Null): 
. 
. 
While(done! =1) 
{ 
    alarm(20); //20 seconds timeout started 
    If(ReadLineMethod()>0) //wait for successful input from stdin 
    { 
     If(inputErr ==1) 
     { 
      **here(for example) I want to print user that timeout  occured and return from the program (exit) ** 
      } 
    alarm(0); 
    done==1; 
    // Do stuff here 
    } 
} 



/* Rest of the program before exit */ 

的同时是要求特定的输入,直到他的类型是正确的或超时将他踢出。

void handler (int signum) 
{ 
inputErr==1;// global parameter 
} 

是否有任何解决方法让我跳过从处理程序返回后读取输入的那一行? 或者至少是管理打印一个正确的消息给用户,超时发生?而不是只是返回并再次卡住输入再次大声笑。

非常感谢。

+0

是的。你可以使用'setjmp()'和'longjmp()'的组合。 – DyZ

+0

为什么不打印并从处理函数本身退出?你可以这样做,如果你退出程序。 – user1952500

+0

那么,你可以通过'siginterrupt(SIGALRM,1)'中断'read'调用,并在'EINTR'错误分支中测试取消标志。然后'longjmp'也应该是信号安全的。如果'ReadLineMethod'不在你自己的控制之下,事情会变得棘手,在这种情况下,你可能需要一些痛苦的黑客,比如关闭标准输入文件描述符。 – doynax

回答

0

使用处理程序引发的标志。用这个标志来调节打印。您需要用互斥锁保护此标志。

+0

放置空调的地方在哪里? 由于处理程序返回到我坚持的If(ReadLineMethod()> 0)行。 – rozmanro

0

如果你不允许重新实现ReadLineMethod()更合理,那么使用线程怎么样?我不是pthread的专家,但你可以设置一些事情,以便在一个线程上发生ReadLineMethod,并且在另一个线程上发生错误轮询。甚至有似乎是一个pthread_cancel可以功能,可以强制停止读取器线程如果需要的话:http://man7.org/linux/man-pages/man3/pthread_cancel.3.html

+1

我已经在这里有很多线程,最好避免使用更多的线程。 谢谢。 – rozmanro

0

因为你有这么多的限制,一个方式来获得在这个系统总量控制将是:

  1. 创建一个线程并在该线程中运行ReadLineMethod()
  2. 创建另一个线程并在该线程中使用一个计时器。不要使用信号,要么检测到陨石已经用完。
  3. 当定时器线程知道定时器已经运行我们的时候,让它杀死(1)中的线程。
  4. 否则,如果ReadLineMethod()已经完全运行完毕,让计时器线程什么也不做并且完成。

当然,这是因为要求而令人费解。如果知道基本要求,可能会有更好的选择。

相关问题