volatile关键字与竞态条件和sigchild信号

volatile限定符从性能的角度取消了编译器的优化,每次读取数据直接从内存中读取,不从编译器中读去内容

Linux下gcc编译器优化:O0无优化 O1缺省,O3最高优化

如以下示例:

主函数与信号处理函数同时对全局变量进行修改和判断。在主函数中因while循环对该全局变量的值只做判断,因此编译器默认的将该变量从内存中拿到寄存器中后,此后直接从寄存器中读取进行判断,相当于一个寄存器变量,而调用信号处理函数之后对该变量在内存中进行了修改,而并未修改寄存器中的值,因此造成了不一致。而对该变量加了volatile限定符后就直接从内存中读取或修改数据。

竞态条件:由于异步事件(指拥有更高优先级的)任何时候都有可能发生,如果写程序时考虑不到位,就有可能由于时序问题导致错误,这就是竞态条件。

上边为自己编写的my_sleep函数;1)先注册信号处理函数2)设置闹钟3)内核调度优先级更的进程取代当前进程执行4) seconds秒钟之后闹钟超时了,内核发送SIGALRM信号给这个进程,处于未决状态 5)优先级更高的进程执行完了,内核要调度回这个进程执行。SIGALRM信号递达,执行处理函数之后再次进入内核 6返回这个进程的主控制流程,alarm(senconds)返回,调pause()挂起等待。

虽然alarm()函数下一句就是pause()函数,但是不能保证pause()会在alarm()后senconds之内调用它,如果在pause()之前屏蔽SIGALRM信号使它不能递达,在调用完毕后再解除屏蔽,但是它们之间也存在缝隙,但该信号仍然有可能被递达,要解决此问题,必须保证挂起等待信号与解除信号屏蔽为原子操作。因此使用sigsuspend()函数能很好的解决该问题。

函数原型:int sigsuspend(const sigset_t* sigmask)

SIGCHILD信号:父进程调用waitpid()以非阻塞式等待子进程退出,子进程在退出后会给父进程发送SIGCHLD信号,主动通知父进程,使父进程回收其子进程资源。父进程可自定义信号处理函数回收子进程,这样父进程就可以每隔一段时间查看是否有子进程退出,其它时间处理自己的事情。

时间: 2024-11-03 22:17:18

volatile关键字与竞态条件和sigchild信号的相关文章

volatile关键字,竟态条件

volatile:防止编译器性能优化,与移植性有关. #include<stdio.h> #include<signal.h> int done=0; void handle(int sig) {     printf("get sig %d\n",sig);     done=1; } int main() {     signal(SIGINT,handle);     while(!done); } Makefile: my_volatile:my_vol

竞态条件

在并发编程中,这种由于不恰当的执行时序而出现不正确的结果是一种非常严重的情况,它有一个正式的名字叫做:竞态条件 使用“先检查后执行”的一种常见情况就是延迟初始化.延迟初始化的目的是将对象的初始化操作推迟到实际被使用时才进行,同时要确保只被初始化一次. @NotThreadSafe public class LazyInitRace { private ExpensiveObject instance = null; public ExpensiveObject getInstance() { i

竞态条件和临界区

1. 临界区和竞态条件: 临界区:访问和操作共享数据的代码段: 竞态条件:当有多个线程同时进入临界区时,执行结果取决于线程的执行顺序: 如下述代码,当多个线程同时调用func函数,对共享数据sum进行操作,实际上我们得到的结果则依赖于执行的相对时间: 线程1在a.取出sum值,然后b.对sum+1,然后c.写入sum值,假设线程2在线程1a步骤之后同样取出sum值,并分别进行+1计算,写回sum值,可见,线程1和线程2计算的结果都是1,此时sum值为1:假设线程2在线程1写回数据之后,取出sum

具有set-uid的应用含有竞态条件漏洞,利用方式。

0x00 含有s标志位的含义 [email protected]:~$ ls -l getuid.exe -rwsr-xr-x 1 beyes beyes 5211 Jun 10 10:45 getuid.exe [email protected]:~$ chmod u+s tuo.a [email protected]:~$ ls -l tuo.a -rwsr-xr-x 1 root root 7567 Jul 8 14:53 tuo.a 这两种在执行时的区别:getuid()geteuid(

Java并发编程:volatile关键字解析(转)

volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用vola

Java并发编程:volatile关键字解析

volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用vola

volatile关键字解析

转载:http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来

6、Java并发编程:volatile关键字解析

Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatil

内存管理_深入剖析volatile关键字

四.深入剖析volatile关键字 在前面讲述了很多东西,其实都是为讲述volatile关键字作铺垫,那么接下来我们就进入主题. 1.volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的. 2)禁止进行指令重排序. 先看一段代码,假如线程1先执行,线程2后执行: //线程1 boolean stop =