当前位置:网站首页 > C++编程 > 正文

c++ 条件变量signal(c++ 条件变量 wait_for)



在这里插入图片描述

1. 引言

在现代操作系统中,信号是一种进程间通信机制,它允许操作系统或其他进程向一个进程发送消息。信号可以用来通知进程发生了一些重要事件,如用户请求终止进程、硬件异常、定时器超时等。掌握信号处理技术对于开发健壮、高效的系统程序至关重要。本文将带你深入了解信号的基础知识,并通过一系列示例演示如何在C语言程序中实现信号处理。

2. 信号概述

信号是由操作系统产生的软件中断,用于通知接收进程发生了某些类型的事件。信号可以分为两大类:

  • 不可忽略的信号:如SIGKILL和SIGSTOP,它们总是会被操作系统强制执行。
  • 可忽略的信号:如SIGINT和SIGTERM,接收进程可以选择忽略或者自定义处理。

常见的信号及其用途如下表所示:

信号编号描述SIGINT2终端中断信号,通常由用户按下Ctrl+C触发。SIGTERM15终止信号,通常用于请求程序优雅地停止运行。SIGKILL9强制终止信号,无法被捕捉或忽略。SIGALRM14定时信号,由alarm()函数设置的时间间隔到期时产生。SIGHUP1挂断信号,当控制终端挂起或登录会话结束时产生。SIGPIPE13管道破裂信号,当写入一个已经断开连接的管道时产生。SIGUSR110用户定义信号1,用于进程间的通讯。SIGUSR212用户定义信号2,用于进程间的通讯。

在这里插入图片描述

3. 信号处理基础

在C语言中,信号处理主要依赖于函数。该函数允许用户注册一个信号处理函数,当指定的信号到达时,就会调用这个函数。然而,函数存在一些限制,如不能传递额外参数给信号处理函数,且不是线程安全的。因此,在多线程程序中,更推荐使用函数来替代。

3.1 使用函数
 

上述代码注册了一个SIGINT信号处理函数,当用户按下Ctrl+C时,程序将打印一条消息并退出。

3.2 使用函数

函数提供了更多的灵活性和安全性,可以设置信号掩码、指定信号处理方式(忽略、默认处理或自定义处理函数)等。

 

在这个版本中,我们使用函数注册了一个信号处理程序,并且启用了标志,这允许我们的信号处理函数接受额外的参数。

在这里插入图片描述

4. 信号与线程

在多线程程序中,信号的处理需要特别注意。默认情况下,信号是针对整个进程而不是特定线程的。这意味着,如果一个线程捕获到了信号,所有线程都会受到影响。为了避免这种情况,可以使用函数来设置线程的信号掩码,从而控制哪些信号可以被线程捕获。

4.1 设置线程信号掩码
 

在此示例中,我们创建了一个线程,并设置了信号掩码,使得只有SIGINT信号可以被线程捕获。这样即使在主线程中按下Ctrl+C,也不会影响到正在运行的线程。

5. 定时信号:与

除了处理外部信号外,我们还可以通过函数来设置定时信号。当指定的时间过去之后,SIGALRM信号就会被发送给进程。此外,函数提供了一种等待信号的方式,并且可以指定一个超时时间。

5.1 使用函数
 

此程序将在启动后五秒发出报警信号。

5.2 使用函数
 

在这个例子中,我们使用函数来等待信号,如果在一秒钟内没有信号到来,则会继续循环。

在这里插入图片描述

6. 高级主题:信号队列与实时信号
6.1 信号队列

当一个信号被发送给一个进程时,如果该信号正在被处理或被阻止,则信号会被放入进程的信号队列中。每个进程都有一个信号队列,最多可以存储一个每个类型的信号。当信号队列已满时,再来的相同类型的信号将被丢弃。

信号队列的管理通常是由操作系统完成的,但作为程序员,我们需要知道信号队列的存在,并且在设计程序时考虑到这一点。例如,如果程序频繁地忽略或阻止某个信号,可能导致信号丢失,从而引发不可预期的行为。

6.2 实时信号

实时信号是一组特殊的信号,它们具有更高的优先级,并且可以携带额外的数据。使用函数可以发送实时信号,并附带一个用户定义的值。

 

这段代码演示了如何发送一个带有整数值的实时信号,并在信号处理函数中读取这个值。

7. 实战案例:实现一个简单的守护进程

守护进程(Daemon)是一种在后台运行的服务程序,它不与任何终端关联,并且通常会在系统启动时自动运行。下面我们将展示如何使用信号处理技术来创建一个简单的守护进程。

7.1 创建守护进程

创建守护进程的一般步骤如下:

  1. 第一次fork:创建一个子进程,然后让父进程退出。这是为了防止后续操作受到shell的影响。
  2. 成为会话领导者:通过调用函数,使进程脱离原来的会话和终端。
  3. 第二次fork:再次创建一个子进程,并让父进程退出。这是因为只能在一个没有控制终端的进程中调用,否则会失败。
  4. 更改工作目录:将当前工作目录改为根目录,防止进程删除其当前目录而导致进程无法正常工作。
  5. 关闭文件描述符:关闭标准输入、输出和错误文件描述符,防止守护进程占用不必要的资源。
  6. 设置信号处理程序:忽略某些信号,使守护进程更加稳定。
 

这个简单的守护进程忽略了大多数信号,只对SIGTERM信号作出响应,即当接收到终止信号时退出。

在这里插入图片描述

8. 高级实战案例:守护进程与信号处理

让我们进一步扩展之前的守护进程示例,使其成为一个更加实用的服务程序。我们将添加日志记录功能,并且允许守护进程通过信号进行重启、停止等操作。

8.1 日志记录

在守护进程中添加日志记录功能可以帮助我们跟踪程序的状态和错误。我们可以将日志输出到一个文件中,这样即使程序崩溃,我们也能够查看到它最后的状态。

 

在这个版本中,我们添加了一个函数,用于将消息输出到日志文件中。同时,我们修改了信号处理函数,使其能够根据不同类型的信号采取不同的行动。

9. 总结与展望

通过本文,你不仅了解了信号的基本概念和用途,还学会了如何在C语言程序中使用信号处理技术。从简单的信号处理到复杂的守护进程创建,每一步都充满了挑战与乐趣。希望这些知识能够帮助你在未来的开发过程中更好地利用信号机制来提升程序的健壮性和可用性。

到此这篇c++ 条件变量signal(c++ 条件变量 wait_for)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • can通讯线故障(can线通讯故障原因)2025-04-09 08:09:07
  • msvcp140d.dll丢失(MSVCP140d.dll丢失下载)2025-04-09 08:09:07
  • cnn神经网络(CNN神经网络全称)2025-04-09 08:09:07
  • cp900墨盒尺寸错误(cp910 墨盒尺寸错误)2025-04-09 08:09:07
  • conda创建虚拟环境怎么删除(conda创建虚拟环境命令)2025-04-09 08:09:07
  • c++单向链表逆序(单链表的逆转c语言)2025-04-09 08:09:07
  • MSVCP140.dll没有被指定在windows上运行(msvcp120.dll没有被指定在windows上运行)2025-04-09 08:09:07
  • dell交换机console口(dell交换机console口波特率)2025-04-09 08:09:07
  • nisc认证(nieh认证)2025-04-09 08:09:07
  • msvcp140_1.dll丢失的解决方法(msvcp140_1.dll丢失的解决方法win11)2025-04-09 08:09:07
  • 全屏图片