【问题标题】:Trouble using system calls无法使用系统调用
【发布时间】:2014-12-22 03:51:03
【问题描述】:

我必须弄清楚如何编写一个循环但不能使用 CTRL-C 5 秒退出的程序,但 5 秒后我可以使用 CTRL-C 结束程序。我一直在阅读系统调用和其他内容,但我不知道从哪里开始。这是确切的说明,如果有人能指出我正确的方向。谢谢。

编写一个 C 程序,该程序使用系统调用创建一个循环,并且在五秒钟内不能被控制 C 杀死。当它开始时,它会打印“我已经开始循环并且不能用 ^C 杀死。 . 。”然后它每秒都会打印一条消息,上面写着“Still looping . . 。” 5 秒后,让控制 C 终止循环并显示消息“我仍在循环,但我可以用 ^C 终止...”每秒显示一次,直到用户终止它。

【问题讨论】:

  • 您可以使用sigaction 来捕获Ctrl-C(SIGINT)。可能在 sigaction 上 example code
  • 一种有趣的方法是将中断字符设置为前 5 秒的 control-T,然后将其设置回 control-C。

标签: c linux unix system


【解决方案1】:

您想查看signal(2) 接口。当 UNIX/Linux 环境中发生某些与进程相关的事件时,操作系统会向进程发送信号(本质上是软件中断)。您可以使用signal 函数“捕获”一个信号,以设置一个回调函数,当给定信号发生时该函数会得到通知。对于 Ctrl-C,您想查看 SIGINT,但您可以使用相同的接口处理其他信号。至于暂停,这很容易 - 只需在循环中使用 sleep()

【讨论】:

  • 我喜欢你让提问者学习如何自助服务的方法,但值得一提的是,sleep() 将阻止该线程上发生的任何工作。
  • 谢谢,我在最初的回答中添加了“循环”。 OP 需要每秒打印一条消息,因此在设置信号处理程序后,他们可以执行此操作(当然只有伪代码):for (number of seconds) do { sleep 1 second; print a message }
  • 使用sigaction() 比使用signal() 更好,尽管使用sigaction() 稍微困难一些。 signal() 存在许多问题,sigaction() 可以避免这些问题。
【解决方案2】:

你可以用这个。

void handler(int signo)
{
  signal(SIGINT,SIG_DFL);
}

main()
{
   signal(SIGINT,SIG_IGN);
   signal(SIGALRM,handler);
   // your code.
   alarm(5);// for 5 seconds.
   while(1)
   { sleep(1);
     printf("your message\n");
   }    
}

首先使用信号忽略 SIGINT。和 sigalrm 的处理程序。所以前 5 秒 ctrl+c 将不起作用。当sigalrm 被发现后 ctrl+c 将起作用。因此,根据您对特定时间段的问题,ctrl+c 将被停止。

【讨论】:

  • 您确定要通过发布完整的程序来为这个人做功课吗?至少这个 OP 只要求指出正确的方向(与许多其他实际要求完整程序的家庭作业相关问题的人不同)。我认为 OP 值得有机会为他/她自己学习。恕我直言。
  • 我不会要求您删除您的答案 - 这完全取决于您。我只是认为很少有提问者真正要求帮助完成他们的家庭作业,而不是要求为他们完成。这让我想给他们发一份“干得好!”电子卡什么的。使用alarm() 与我的方法不同,它提供了signal 的其他用途示例,因此OP 可能会从作业中学到更多东西。您可能想为他们分配额外的作业:“使用这种方法,您如何仍然每秒钟打印一次消息?”
猜你喜欢
  • 1970-01-01
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多