Linux下semop等待信号时出现Interrupted System Call错误(EINTR)解决方法

错误现象:(semop函数调用,strerror(errno)输出结果)
Interrupted system call
平台:RedHat Linux

LINUX文档关于EINTR的描述是这样子的:
  While blocked in this system call, the process caught a signal.
UNIX文档[IEEE Std 1003.1-2008]关于EINTR的描述是这样子的:
  The semop() function was interrupted by a signal.

这样的两句话如果关从字面上理解的话,就是在semop等待的过程中出现INTR信号。
可是,错误的出现需要解决,错误的原因一般是由程序员写的代码造成的。
经过调试输出定位问题原因,终于找到了问题所有:
当semop正在等待资源时,如果这个时候,该进程中某线程使用system调用SHELL函数时,semop立即返回,并且错误号为EINTR,错误信息如上。别看这样一个小问题,在我的系统中,由于使用了多种手段来实现IPC(进程内通信),要打到原因是由于一个system的调用就不是那么简单了。

[因为网络上这个问题解决方案暂时没有找到,希望能给他人帮助]

该错误我在GOOGLE上搜了一些贴子,有一位仁兄曾说过:由于死锁导致
因为信号量本身就是防止出现死锁。我特意做了一下实验,使用一个互斥变量和一个信号量,以及两个信号量,以不同顺序,以实现死锁,可是系统并未出现我期望的“Interrupted system call”,而只是一味的等待。

今天在看《UNIX网络编程第1卷 套接口API》时,看到了这样的一句话,让我理解了为什么会出现这个错误,原文如下:
“适用于慢系统调用的基本规则是:当阻塞于某个慢系统调用的一个进程捕获某个信号且相应信号处理函数返回时,该系统调用可能返回一个EINTR错误。有些内核自动重启某些被中断的系统调用。”
在这里,慢系统调用(slow system call)在书中是指类似accept之类的引起阻塞的函数,而上文讨论过的semop函数,我想应该也是这一类的,所以当现现EINTR信号时,该系统调用被中断,并返回错误,错误号为:EINTR,我们就可以从这个错误号来重新启动我们的系统调用。

(0)

相关推荐

  • Linux系统(X64)安装Oracle11g完整安装图文教程另附基本操作

    一.修改操作系统核心参数 在Root用户下执行以下步骤: 1)修改用户的SHELL的限制,修改/etc/security/limits.conf文件 输入命令:vi /etc/security/limits.conf,按i键进入编辑模式,将下列内容加入该文件. oracle soft nproc 2047 oracle hard nproc 16384 oracle soft nofile 1024 oracle hard nofile 65536 编辑完成后按Esc键,输入":wq"

  • linux多线程编程详解教程(线程通过信号量实现通信代码)

    线程分类 线程按照其调度者可以分为用户级线程和核心级线程两种. (1)用户级线程 用户级线程主要解决的是上下文切换的问题,它的调度算法和调度过程全部由用户自行选择决定,在运行时不需要特定的内核支持.在这里,操作系统往往会提供一个用户空间的线程库,该线程库提供了线程的创建.调度.撤销等功能,而内核仍然仅对进程进行管理.如果一个进程中的某一个线程调用了一个阻塞的系统调用,那么该进程包括该进程中的其他所有线程也同时被阻塞.这种用户级线程的主要缺点是在一个进程中的多个线程的调度中无法发挥多处理器的优势.

  • linux下基于C语言的信号编程实例

    本文实例讲述了linux下基于C语言的信号编程方法.分享给大家供大家参考.具体如下: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> void sig_handler(int sig_no, siginfo_t *info, void *ctext){ printf("receive si

  • Android获取当前已连接的wifi信号强度的方法

    本文实例讲述了Android获取当前已连接的wifi信号强度的方法,是Android程序开发中非常常见的重要技巧.分享给大家供大家参考之用.具体方法如下: 1.得到当前已连接的wifi信息 WifiManager wifi_service = (WifiManager)getSystemService(WIFI_SERVICE); WifiInfo wifiInfo = wifi_service.getConnectionInfo(); 其中wifiInfo有以下的方法: wifiinfo.ge

  • Linux线程同步之信号C语言实例

    linux中向某个线程发送信号,若没有对该信号的处理函数,则会导致程序结束. 如下面的程序,创建一个线程,主线程向其发送一个信号,会导致程序立即结束 #include <stdio.h> #include <pthread.h> pthread_t t; void* run(void* arg) { while(1) { printf("Hello\n"); } } main() { pthread_create(&t, 0, run, 0); pthr

  • Linux下的信号详解及捕捉信号

    信号的基本概念 每个信号都有一个编号和一个宏定义名称 ,这些宏定义可以在 signal.h 中找到. 使用kill -l命令查看系统中定义的信号列表: 1-31是普通信号: 34-64是实时信号 所有的信号都由操作系统来发! 对信号的三种处理方式 1.忽略此信号:大多数信号都可使用这种方式进行处理,但有两种信号却决不能被忽略.它们是:SIGKILL和SIGSTOP.这两种信号不能被忽略的,原因是:它们向超级用户提供一种使进程终止或停止的可靠方法.另外,如果忽略某些由硬件异常产生的信号(例如非法存

  • Python Web框架Flask信号机制(signals)介绍

    信号(signals) Flask信号(signals, or event hooking)允许特定的发送端通知订阅者发生了什么(既然知道发生了什么,那我们可以知道接下来该做什么了). Flask提供了一些信号(核心信号)且其它的扩展提供更多的信号.信号是用于通知订阅者,而不应该鼓励订阅者修改数据.相关信号请查阅文档. 信号依赖于Blinker库. 钩子(hooks) Flask钩子(通常出现在蓝图或应用程序现存的方法中,比如一些内置装饰器,例如before_request)不需要Blinker

  • java信号量控制线程打印顺序的示例分享

    复制代码 代码如下: import java.util.concurrent.Semaphore; public class ThreeThread { public static void main(String[] args) throws InterruptedException {  Semaphore sempA = new Semaphore(1);  Semaphore sempB = new Semaphore(0);  Semaphore sempC = new Semapho

  • linux shell中 if else以及大于、小于、等于逻辑表达式介绍

    比如比较字符串.判断文件是否存在及是否可读等,通常用"[]"来表示条件测试. 注意:这里的空格很重要.要确保方括号的空格.笔者就曾因为空格缺少或位置不对,而浪费好多宝贵的时间. if ....; then....elif ....; then....else....fi[ -f "somefile" ] :判断是否是一个文件[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限[ -n "$var" ]

  • Linux下semop等待信号时出现Interrupted System Call错误(EINTR)解决方法

    错误现象:(semop函数调用,strerror(errno)输出结果)Interrupted system call平台:RedHat Linux LINUX文档关于EINTR的描述是这样子的:  While blocked in this system call, the process caught a signal.UNIX文档[IEEE Std 1003.1-2008]关于EINTR的描述是这样子的:  The semop() function was interrupted by a

  • Hadoop运行时遇到java.io.FileNotFoundException错误的解决方法

    报错信息: java.lang.Exception: org.apache.hadoop.mapreduce.task.reduce.Shuffle$ShuffleError: error in shuffle in localfetcher#1 at org.apache.hadoop.mapred.LocalJobRunner$Job.runTasks(LocalJobRunner.java:462) at org.apache.hadoop.mapred.LocalJobRunner$Jo

  • 安装sql server 2008时的4个常见错误和解决方法

    可能由于操作系统不同,或者在安装SQL 2008的时候已经安装SQL其他版本,因此可能会遇到问题,那么这时我们的实际经验和动手测试的能力也是非常重要的,这样才能少走弯路. 问题1:安装sql server 2008 R2,安装过程中提示错误:此计算机上安装了 Microsoft Visual Studio 2008 的早期版本.请在安装 SQL Server 2008 前将 Microsoft Visual Studio 2008 升级到 SP1. 之前我的电脑上确实装了vs2008,于是我准

  • 使用 SQL 服务器时,"评估期已过期"错误消息(解决方法)

    当打开sql server2008企业管理器的时候,出现报错"评估期已过.有关如何升级的测试版软件的信息....." 修改注册表:HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SQL Server/100/ConfigurationState里的 CommonFiles 值改成 3 进入SQL2008配置工具中的安装中心 再进入维护界面,选择版本升级 进入产品密钥,输入密钥JD8Y6-HQG69-P9H84-XDTPG-34MBB 一直

  • Nodejs下用submit提交表单提示cannot post错误的解决方法

    <span style="font-size:18px;"><form action="/registOK" method="get"> <p>用户名:<input type="text" id="userName" name="userName"></p> <p>密码:<input type="pa

  • 64位系统中IIS7运行ASP时出现ADODB.Connection 800a0e7a错误的解决方法

    今天将一个ASP网站拷贝到64位的Windows7中运行,IIS7安装都没有问题,可就是死活运行不了,总是出现ADODB.Connection错误"800a0e7a",真是奇怪,之前在XP中运行一点问题都没有的.起初以为是代码上的原因,于是写一段最简单的连接数据库的代码,还是出错,研究半天终于找到了解决方法,拿来分享. 原因是因为在64位Windows7操作系统中,IIS7应用程序池默认没有启用32位应用程序,而我们连接ACCESS数据库的驱动程序Microsoft.Jet.OLEDB

  • 浅析Dos下运行php.exe,出现没有找到php_mbstring.dll 错误的解决方法

    在php.ini文件中将 extension=php_mbstring.dll 移动到 extension=php_exif.dll 之前. 因为 exif 要调用 mbstring, 所以 mbstring 必须在前面. php_exif.dll, EXIF 函数库,需要 php_mbstring.dll. 并且在 php.ini 中, php_exif.dll 必须在 php_mbstring.dll 之后加载. 如若不行,则检查 php.ini 中默认的 extension_dir 值是否

  • Linux下Oracle中SqlPlus时上下左右键乱码问题的解决办法

    window下的sqlplus可以通过箭头键,来回看历史命令,用起来非常的方便. 但是在Linux下,会出现各种乱码,非常不方便,如下图所示,每次打错一个字符就需要重新打一遍. 解决办法:rlwrap 可以用来支持Oracle下sqlplus历史命令的回调功能,提高效率. 解决过程: 1.首先下载rlwrap和readline: readline-6.3.tar.gz rlwrap-0.30.tar.gz 2.安装readline包 tar -zxvf readline-6.3.tar.gz c

  • Linux程序运行时加载动态库失败的解决方法

    Linux下不能加载动态库问题 当出现下边异常情况 ./test: error while loading shared libraries: libmfs_open.so: cannot open shared object file: No such file or directory 若动态库的路径在(/usr/cluster/.share/lib) 解决办法: 方法一.在/etc/ld.so.conf文件中添加路径,vi /etc/ld.so.conf 添加下边内容 include ld

  • Linux下安装Python3和django并配置mysql作为django默认服务器方法

    我的操作系统为centos6.5 1  首先选择django要使用什么数据库.django1.10默认数据库为sqlite3,本人想使用mysql数据库,但为了测试方便顺便要安装一下sqlite开发包. yum install mysql mysql-devel #为了测试方便,我们需要安装sqlite-devel包 yum install sqlite-devel 2  接下来需要安装Python了,因为Python3已经成为主流,所以接下来我们要安装Python3,到官网去下载Python3

随机推荐