导航:首页 > 操作系统 > linux进程间信号量

linux进程间信号量

发布时间:2023-10-05 12:02:09

linux常用信号量

  1. BUS与SEGV
    二者都是错误信号,BUS表示总线错误,SEGV表示段错误,程序崩溃的时候99%都是这两个错误导
    致的。进程可以捕获和封锁这两类错误。内核对二者的默认处理是memory mp

  2. WINCH
    窗口改变信号(WINdown CHanged)。例如虚拟终端的行数发生变化时将发送WINCH信号,绝大多数
    文本编辑器都能捕获WINCH信号自动进行重新配置。内核的默认处理是忽略该信号,并且不进行内存
    转储。
    进程可以捕获或者封锁该信号

  3. KILL
    杀死/删除进程,编号为9

  4. STOP
    挂起/暂停正在执行的进程,直到收到CONT为止
    KILL STOP都不能够被捕获、封锁或者忽略,默认处理都不会产生内存转储。

  5. CONT
    取消挂起,继续执行进程

  6. TSTP
    是STOP信号的“软”版本,即在用户输入Ctrl+Z时由终端驱动程序发送的信号。捕获到该信号的进程通常
    清除它们的状态,如何给自己发送一个STOP信号。TSTP的默认处理不会导致内存转储。

  7. INT
    中断信号,编号为2
    当用户输入Ctrl+C时由终端驱动程序发送INT信号
    INT信号是终止当前操作的请求,简单程序捕获到INT信号时应该退出,拥有命令行或者输入模式的那些
    程序应该停止他们正在做的事情,清除状态,并等待用户再次输入。

  8. TERM
    软件终止信号,编号为15
    TERM是请求彻底终止某项操作的信号,它期望进程清楚自己的状态并退出

  9. QUIT
    退出信号,编号为3
    与TERM类似,不同之处在于QUIT信号的默认处理是内存转储,而TERM信号的默认处理没有内存转储。

  10. HUP
    挂起信号,编号为1,有两种解释:
    守护进程理解HUP为重新设置的请求,如果守护进程能够不用重新启动就能够重新读取它自己的配置文
    件并调整自己以适应变化的话,那么HUP信号通常可以用来触发这种行为

  11. HUP
    信号有时有终端驱动程序生成,试图用来清除(也就是终止)跟某个特定终端相连接的那些进程。例如
    当一个终端会话结束时,或者当一个Modem的连接不经意的断开时,就可能出现这种情况。
    如果需要某些进程在会话结束之后继续运行,那么在C Shell中设法让这些进程变成后台程序,
    ksh或者bash中可以用nohup来模拟这种行为。
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    进程的四种状态

  12. runnable(可运行状态)
    只要有CPU时间,进程就可以执行。一旦进程执行了不能立即完成的系统调用,Linux会把进程转入
    睡眠状态

  13. sleeping(睡眠状态)
    进程在等待某些事件发生(如终端输入、网络连接)

  14. zombie(僵化状态)
    进程已经执行完毕并试图消亡,但是状态没有收集完

  15. stopped(停止状态)
    进程被挂起,不允许执行。进程收到STOP或者TSTP信号即进入停止状态,可以用CONT信号来重新启动

⑵ linux 信号灯和信号量的区别

信号量是与signal相关的内容,是进程间通信的一种方式,一个进程可以向另一个进程发送一个信号作为通知,除了signal系统调用外,相关内容还有:

SEE ALSO
kill(1), alarm(2), kill(2), killpg(2), pause(2), sigaction(2), signalfd(2), sigpending(2), sigprocmask(2), sigsuspend(2), bsd_signal(3), raise(3), sigin-
terrupt(3), sigqueue(3), sigsetops(3), sigvec(3), sysv_signal(3), signal(7)

信号量也是进程通信的一种方式,一般用于并发取得资源对应锁或者其他互斥操作,除了semget系统调用外,相关内容还有:

SEE ALSO
semctl(2), semop(2), ftok(3), capabilities(7), sem_overview(7), svipc(7)

⑶ Linux信号 机制和Linux信号量机制的区别

首先,一句话总结它们之间的区别:

字面上相似,但是本质上存在巨大的差别!请看详细解答...
Linux信号(signal) 机制

signal,又简称为信号(软中断信号)用来通知进程发生了异步事件。

原理:

一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。信号机制除了基本通知功能外,还可以传递附加信息。

分类:
从两个不同的分类角度对信号进行:
可靠性方面:可靠信号与不可靠信号;
与时间的关系上:实时信号与非实时信号。

部分定义转自:http://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html

Linux信号量(semaphore)机制
Linux内核的信号量用来操作系统进程间同步访问共享资源。

原理:信号量在创建时需要设置一个初始值,表示同时可以有几个任务可以访问该信号量保护的共享资源,初始值为1就变成互斥锁(Mutex),即同时只能有一个任务可以访问信号量保护的共享资源。
一个任务要想访问共享资源,首先必须得到信号量,获取信号量的操作将把信号量的值减1,若当前信号量的值为负数,表明无法获得信号量,该任务必须挂起在该信号量的等待队列等待该信号量可用;若当前信号量的值为非负数,表示可以获得信号量,因而可以立刻访问被该信号量保护的共享资源。
当任务访问完被信号量保护的共享资源后,必须释放信号量,释放信号量通过把信号量的值加1实现,如果信号量的值为非正数,表明有任务等待当前信号量,因此它也唤醒所有等待该信号量的任务。

常用的信号量的API:

DECLARE_MUTEX(name)

该宏声明一个信号量name并初始化它的值为0,即声明一个互斥锁。
DECLARE_MUTEX_LOCKED(name)

该宏声明一个互斥锁name,但把它的初始值设置为0,即锁在创建时就处在已锁状态。因此对于这种锁,一般是先释放后获得。
void sema_init (struct semaphore *sem, int val);

该函用于数初始化设置信号量的初值,它设置信号量sem的值为val。
void init_MUTEX (struct semaphore *sem);

该函数用于初始化一个互斥锁,即它把信号量sem的值设置为1。
void init_MUTEX_LOCKED (struct semaphore *sem);

该函数也用于初始化一个互斥锁,但它把信号量sem的值设置为0,即一开始就处在已锁状态。
void down(struct semaphore * sem);

该函数用于获得信号量sem,它会导致睡眠,因此不能在中断上下文(包括IRQ上下文和softirq上下文)使用该函数。该函数将把sem的值减1,如果信号量sem的值非负,就直接返回,否则调用者将被挂起,直到别的任务释放该信号量才能继续运行。
int down_interruptible(struct semaphore * sem);

该函数功能与down类似,不同之处为,down不会被信号(signal)打断,但down_interruptible能被信号打断,因此该函数有返回值来区分是正常返回还是被信号中断,如果返回0,表示获得信号量正常返回,如果被信号打断,返回-EINTR。
int down_trylock(struct semaphore * sem);

该函数试着获得信号量sem,如果能够立刻获得,它就获得该信号量并返回0,否则,表示不能获得信号量sem,返回值为非0值。因此,它不会导致调用者睡眠,可以在中断上下文使用。
void up(struct semaphore * sem);

该函数释放信号量sem,即把sem的值加1,如果sem的值为非正数,表明有任务等待该信号量,因此唤醒这些等待者。

实例:
信号量在绝大部分情况下作为互斥锁使用,下面以console驱动系统为例说明信号量的使用。

在内核源码树的kernel/printk.c中,使用宏DECLARE_MUTEX声明了一个互斥锁console_sem,它用于保护console驱动列表console_drivers以及同步对整个console驱动系统的访问。

⑷ Linux信号量

信号量是包含一个非负整数型的变量,并且带有两个原子操作wait和signal。Wait还可以被称为down、P或lock,signal还可以被称为up、V、unlock或post。在UNIX的API中(POSIX标准)用的是wait和post。

对于wait操作,如果信号量的非负整形变量S大于0,wait就将其减1,如果S等于0,wait就将调用线程阻塞;对于post操作,如果有线程在信号量上阻塞(此时S等于0),post就会解除对某个等待线程的阻塞,使其从wait中返回,如果没有线程阻塞在信号量上,post就将S加1.

由此可见,S可以被理解为一种资源的数量,信号量即是通过控制这种资源的分配来实现互斥和同步的。如果把S设为1,那么信号量即可使多线程并发运行。另外,信号量不仅允许使用者申请和释放资源,而且还允许使用者创造资源,这就赋予了信号量实现同步的功能。可见信号量的功能要比互斥量丰富许多。

POSIX信号量是一个sem_t类型的变量,但POSIX有两种信号量的实现机制: 无名信号量 命名信号量 。无名信号量只可以在共享内存的情况下,比如实现进程中各个线程之间的互斥和同步,因此无名信号量也被称作基于内存的信号量;命名信号量通常用于不共享内存的情况下,比如进程间通信。

同时,在创建信号量时,根据信号量取值的不同,POSIX信号量还可以分为:

下面是POSIX信号量函数接口:

信号量的函数都以sem_开头,线程中使用的基本信号函数有4个,他们都声明在头文件semaphore.h中,该头文件定义了用于信号量操作的sem_t类型:

【sem_init函数】:

该函数用于创建信号量,原型如下:

该函数初始化由sem指向的信号对象,设置它的共享选项,并给它一个初始的整数值。pshared控制信号量的类型,如果其值为0,就表示信号量是当前进程的局部信号量,否则信号量就可以在多个进程间共享,value为sem的初始值。

该函数调用成功返回0,失败返回-1。

【sem_destroy函数】:

该函数用于对用完的信号量进行清理,其原型如下:

成功返回0,失败返回-1。

【sem_wait函数】:

该函数用于以原子操作的方式将信号量的值减1。原子操作就是,如果两个线程企图同时给一个信号量加1或减1,它们之间不会互相干扰。其原型如下:

sem指向的对象是sem_init调用初始化的信号量。调用成功返回0,失败返回-1。

sem_trywait()则是sem_wait()的非阻塞版本,当条件不满足时(信号量为0时),该函数直接返回EAGAIN错误而不会阻塞等待。

sem_timedwait()功能与sem_wait()类似,只是在指定的abs_timeout时间内等待,超过时间则直接返回ETIMEDOUT错误。

【sem_post函数】:

该函数用于以原子操作的方式将信号量的值加1,其原型如下:

与sem_wait一样,sem指向的对象是由sem_init调用初始化的信号量。调用成功时返回0,失败返回-1。

【sem_getvalue函数】:

该函数返回当前信号量的值,通过restrict输出参数返回。如果当前信号量已经上锁(即同步对象不可用),那么返回值为0,或为负数,其绝对值就是等待该信号量解锁的线程数。

【实例1】:

【实例2】:

之所以称为命名信号量,是因为它有一个名字、一个用户ID、一个组ID和权限。这些是提供给不共享内存的那些进程使用命名信号量的接口。命名信号量的名字是一个遵守路径名构造规则的字符串。

【sem_open函数】:

该函数用于创建或打开一个命名信号量,其原型如下:

参数name是一个标识信号量的字符串。参数oflag用来确定是创建信号量还是连接已有的信号量。

oflag的参数可以为0,O_CREAT或O_EXCL:如果为0,表示打开一个已存在的信号量;如果为O_CREAT,表示如果信号量不存在就创建一个信号量,如果存在则打开被返回,此时mode和value都需要指定;如果为O_CREAT|O_EXCL,表示如果信号量存在则返回错误。

mode参数用于创建信号量时指定信号量的权限位,和open函数一样,包括:S_IRUSR、S_IWUSR、S_IRGRP、S_IWGRP、S_IROTH、S_IWOTH。

value表示创建信号量时,信号量的初始值。

【sem_close函数】:

该函数用于关闭命名信号量:

单个程序可以用sem_close函数关闭命名信号量,但是这样做并不能将信号量从系统中删除,因为命名信号量在单个程序执行之外是具有持久性的。当进程调用_exit、exit、exec或从main返回时,进程打开的命名信号量同样会被关闭。

【sem_unlink函数】:

sem_unlink函数用于在所有进程关闭了命名信号量之后,将信号量从系统中删除:

【信号量操作函数】:

与无名信号量一样,操作信号量的函数如下:

命名信号量是随内核持续的。当命名信号量创建后,即使当前没有进程打开某个信号量,它的值依然保持,直到内核重新自举或调用sem_unlink()删除该信号量。

无名信号量的持续性要根据信号量在内存中的位置确定:

很多时候信号量、互斥量和条件变量都可以在某种应用中使用,那这三者的差异有哪些呢?下面列出了这三者之间的差异:

⑸ Linux进程通信实验(共享内存通信,接上篇)

这一篇记录一下共享内存实验,需要linux的共享内存机制有一定的了解,同时也需要了解POSIX信号量来实现进程间的同步。可以参考以下两篇博客: https://blog.csdn.net/sicofield/article/details/10897091
https://blog.csdn.net/ljianhui/article/details/10253345

实验要求:编写sender和receiver程序,sender创建一个共享内存并等待用户输入,然后把输入通过共享内存发送给receiver并等待,receiver收到后把消息显示在屏幕上并用同样方式向sender发送一个over,然后两个程序结束运行。
这个实验的难点主要在于共享内存的创建和撤销(涉及到的步骤比较多,需要理解各步骤的功能),以及实现两个进程间的相互等待(使用信号量来实现,这里使用了有名信号量)

实验心得:学习理解了linux的共享内存机制以及POSIX信号量机制。
两个实验虽然加强了对linux一些机制的理解,但是感觉对linux的学习还不够,需要继续学习。

阅读全文

与linux进程间信号量相关的资料

热点内容
sql如何查看服务器地址 浏览:775
编译速度和系统有关吗 浏览:56
复盛制冷压缩机 浏览:979
云服务器共享手机流量 浏览:833
星界边境像素压缩 浏览:459
算法分析与设计二手 浏览:983
学编程如何配电脑 浏览:971
怎么看特征找卡密的加密方式 浏览:526
方舟非官方服务器怎么赚钱 浏览:516
明日之后服务器无效是怎么回事 浏览:270
蛋壳公寓app如何查水电表 浏览:718
ad20库中的51单片机怎么找 浏览:624
阿里云服务器有点卡吗 浏览:215
苹果7如何让app后台运行 浏览:170
耐克app预售产品哪里看 浏览:209
补全算法一年级 浏览:131
evd数据调校软件加密 浏览:442
app听课与微信如何设置分屏 浏览:911
加密的excel怎么撤销 浏览:43
java动态数组初始化 浏览:978