linux系统编程之信号(六) 竞态条件与sigsuspend函数

一、利用pause和alarm函数实现sleep函数

#include <unistd.h>

int pause(void);

pause函数使调用进程挂起直到有信号递达。如果信号的处理动作是终止进程,则进程终止,pause函数没有机会返回;如果信号的处理动作是忽略,则进程继续处于挂起状态,pause不返回;如果信号的处理动作是捕捉,则调用了信号处理函数之后pause返回-1,errno设置为EINTR,所以pause只有出错的返回值。错误码EINTR表示“被信号中断”。

alarm函数可以参考这里:http://blog.csdn.net/simba888888/article/details/8944647

下面使用pause和alarm实现sleep(3)函数,称为mysleep:

#include<stdio.h>
#include<signal.h>
#include<unistd.h>

void sig_alrm(int signo)
{
    /* nothing to do */
}

unsigned int mysleep(unsigned int nsecs)
{
    struct sigaction newact, oldact;
    unsigned int unslept;

    newact.sa_handler = sig_alrm;
    sigemptyset(&newact.sa_mask);
    newact.sa_flags = 0;
    sigaction(SIGALRM, &newact, &oldact);

    alarm(nsecs);
    pause();

    unslept = alarm(0);
    sigaction(SIGALRM, &oldact, NULL);

    return unslept;
}

int main(void)
{
    while (1)
    {
        mysleep(2);
        printf("Two seconds passed\n");
    }
    return 0;
}

1. main函数调用mysleep函数,后者调用sigaction注册了SIGALRM信号的处理函数sig_alrm。

2. 调用alarm(nsecs)设定闹钟。

3. 调用pause等待,内核切换到别的进程运行。

4. nsecs秒之后,闹钟超时,内核发SIGALRM给这个进程。

5. 从内核态返回这个进程的用户态之前处理未决信号,发现有SIGALRM信号,其处理函数是sig_alrm。

6. 切换到用户态执行sig_alrm函数,进入sig_alrm函数时SIGALRM信号被自动屏蔽,从sig_alrm函数返回时SIGALRM信号自动解除屏蔽。然后自动执行系统调用sigreturn再次进入内核,再返回用户态继续执行进程的主控制流程(main函数调用的mysleep函数)。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索函数
, 内核
, 进程
, 信号
, alarm
pause
sigsuspend、sigsuspend详解、sigsuspend 函数、rt sigsuspend、linux sigsuspend,以便于您获取更多的相关知识。

时间: 2024-11-03 02:02:22

linux系统编程之信号(六) 竞态条件与sigsuspend函数的相关文章

linux系统编程之信号(二) 信号发送函数及不同精度的睡眠

一.kill, raise, killpg 函数 int kill(pid_t pid, int sig); int raise(int sig); int killpg(int pgrp, int sig); kill命令是调用kill函数实现的,kill函数可以给一个指定的进程或进程组发送指定的信号,其中kill 函数的pid 参数取值不同表示不同含义,具体可man 一下.raise函数可以给当前进程发送指定的信号(自己给自己发信号).killpg 函数可以给进程组发生信号.这三个函数都是成

linux系统编程之信号(一) 信号概述

一.为了理解信号,先从我们最熟悉的场景说起: 1. 用户输入命令,在Shell下启动一个前台进程. 2. 用户按下Ctrl-C,这个键盘输入产生一个硬件中断. 3. 如果CPU当前正在执行这个进程的代码,则该进程的用户空间代码暂停执行,CPU从用户态切换到内核态处理硬件中断. 4. 终端驱动程序将Ctrl-C解释成一个SIGINT信号,记在该进程的PCB中(也可以说发送了一个SIGINT信号给该进程). 5. 当某个时刻要从内核返回到该进程的用户空间代码继续执行之前,首先处理PCB中记录的信号,

linux系统编程之信号(四) 信号的捕捉与sigaction函数

一.内核如何实现信号的捕捉 如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号.由于信号处理函数的代码是在用户空间的,处理过程比较复杂,举例如下: 1. 用户程序注册了SIGQUIT信号的处理函数sighandler. 2. 当前正在执行main函数,这时发生中断或异常切换到内核态. 3. 在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达. 4. 内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函数,s

linux系统编程之信号(五) 实时信号与sigqueue函数

一.sigqueue函数 功能:新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用. 原型:int sigqueue(pid_t pid, int sig, const union sigval value); 参数: sigqueue的第一个参数是指定接收信号的进程id,第二个参数确定即将发送的信号,第三个参数是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值. 返回值:成功返回0,失败返回-1 typede

linux系统编程之信号(三) 信号的阻塞与未决

一.信号在内核中的表示 实际执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending).进程可以选择阻塞(Block)某个信号.被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作.信号在内核中的表示可以看作是这样的: 每个信号都有两个标志位分别表示阻塞和未决,还有一个函数指针表示处理动作.信号产生时,内核在进程控制块中设置该信

LINUX系统编程 LINUX 虚拟内存

LINUX 虚拟内存 以32位操作系统为例子,因为64位系统虚拟地址过大为2^64,32位仅仅为2^32=4G更利于描述,但是原理东西都一样 这首先要从程序和进程之间的关系开始,我们一般写好一段C\C++代码编译后仅仅为可执行文件假设为a.out,我们 运行a.out的时候,这个才叫进程,进程是OS级别抽象的实体(PCB task_struct结构体),为程序运行进行各种检查和 系统资源分配,一个PCB包含部分信息如下: (摘至刑文鹏LINUX系统编程讲义) * 进程id.系统中每个进程有唯一的

linux系统编程之文件与I/O(六) fcntl函数与文件锁

一.fcntl函数 功能:操纵文件描述符,改变已打开的文件的属性 int fcntl(int fd, int cmd, ... /* arg */ ); cmd的取值可以如下: 复制文件描述符 F_DUPFD (long) 设置/获取文件描述符标志 F_GETFD (void) F_SETFD (long) 设置/获取文件状态标志 F_GETFL (void) F_SETFL (long) 获取/设置文件锁 F_GETLK F_SETLK,F_SETLKW 其中复制文件描述符可参见<linux系

《Linux系统编程(第2版)》——导读

前言 这本书是关于Linux上的系统编程."系统编程"是指编写系统软件,其代码在底层运行,直接跟内核和核心系统库对话.换句话说,本书的主题是Linux系统调用和底层函数说明,如C库定义的函数. 虽然已经有很多书探讨UNIX上的系统编程,却很少有专注于探讨Linux方面的书籍,而探讨最新版本的Linux以及Linux特有的高级接口的书籍更是凤毛麟角.此外,本书还有一个优势:我为Linux贡献了很多代码,包括内核及其上面的系统软件.实际上,本书中提到的一些系统调用和系统软件就是我实现的.因

《Linux系统编程(第2版)》——1.4 Linux编程的概念

1.4 Linux编程的概念 本节给出了Linux系统提供的服务的简要概述.所有的UNIX系统,包括Linux,提供了共同的抽象和接口集合.实际上,UNIX本身就是由这些共性定义的,比如对文件和进程的抽象.管道和socket的管理接口等等,都构成了UNIX系统的核心. 本概述假定你对Linux环境很熟悉:会使用shell的基础命令.能够编译简单的C程序.它不是关于Linux或其编程环境的,而是关于Linux系统编程的基础. 1.4.1 文件和文件系统文件是Linux系统中最基础最重要的抽象.Li