当前位置:首页 » 操作系统 » linuxc信号量

linuxc信号量

发布时间: 2022-03-11 23:24:35

linux C编程 信号量sys/sem 有等待超时么

可以用semtimedop

Ⅱ 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进程间信号量的等待投递

每个信号量都具有一个非负的值,且信号量支持等待和投递操作。系统调用 semop 实现了这两个操作。它的第一个参数是信号量的标识符,第二个参数是一个包含 struct sembuf 类型元素的数组;这些元素指明了您希望执行的操作。第三个参数是这个数组的长度。结构体sembuf中包含如下字段:
sem_num将要执行操作的信号量组中包含的信号量数量。 sem_op是一个指定了操作类型的整数。 如果sem_op是一个正整数,则这个值会立刻被加到信号量的值上。 [BR]如果 sem_op 为负,则将从信号量值中减去它的绝对值。如果这将使信号量的值小于零,则这个操作会导致进程阻塞,直到信号量的值至少等于操作值的绝对值(由其它进程增加它的值)。 [BR]如果 sem_op 为0,这个操作会导致进程阻塞,直到信号量的值为零才恢复。 sem_flg 是一个符号位。指定 IPC_NOWAIT 以防止操作阻塞;如果该操作本应阻塞,则semop调用会失败。如果为sem_flg指定SEM_UNDO,Linux会在进程退出的时候自动撤销该次操作。 代码 5.4 展示了二元信号量的等待和投递操作。
代码 5.4 (sem_pv.c)二元信号量等待和投递操作
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/* 等待一个二元信号量。阻塞直到信号量的值为正,然后将其减1 */
int binary_semaphore_wait (int semid)
{
struct sembuf operations[1];
/* 使用(且仅使用)第一个信号量 */
operations[0].sem_num = 0;
/* 减一。 */
operations[0].sem_op = -1;
/* 允许撤销操作 */
operations[0].sem_flg = SEM_UNDO;
return semop (semid, operations, 1);
}
/* 对一个二元信号量执行投递操作:将其值加一。 这个操作会立即返回。*/
int binary_semaphore_post (int semid)
{
struct sembuf operations[1];
/* 使用(且仅使用)第一个信号量 */
operations[0].sem_num = 0;
/* 加一 */
operations[0].sem_op = 1;
/* 允许撤销操作 */
operations[0].sem_flg = SEM_UNDO;
return semop (semid, operations, 1);
}
指定 SEM_UNDO 标志解决当出现一个进程仍然持有信号量资源时被终止这种特殊情况时可能出现的资源泄漏问题。当一个进程被有意识或者无意识地结束的时候,信号量的值会被调整到“撤销”了所有该进程执行过的操作后的状态。例如,如果一个进程在被杀死之前减小了一个信号量的值,则该信号量的值会增长。

Ⅳ 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 +c 代码 ,分别用posix共享内存+posix信号量,SystemV共享内存+SystemV信号量实现生产者和消费者例

挺简单啊,信号+共享内存,这种例子很多啊

Ⅵ linux进程间信号量的初始信号

分配与初始化信号量是两个相互独立的操作。以 0 为第二参数,以 SETALL 为第三个参数调用 semctl 可以对一个信号量组进行初始化。第四个参数是一个 semun 对象,且它的 array 字段指向一个 unsigned short数组。数组中的每个值均用于初始化该组中的一个信号量。
代码 5.3 展示了初始化一个二元信号量的函数。
代码 5.3 (sem_init.c) 初始化一个二元信号量
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
/* 我们必须自己定义 union semun。*/
union semun
{
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
/* 将一个二元信号量初始化为 1。*/
int binary_semaphore_initialize (int semid)
{
union semun argument;
unsigned short values[1];
values[0] = 1;
argument.array = values;
return semctl (semid, 0, SETALL, argument);
}

Ⅶ linux下的Ctrl+C信号值是多少,该如何解决

Ctrl+C:送SIGINT信号,默认进程会结束,但是进程自己可以重定义收到这个信号的行为。 Ctrl+Z:送SIGSTOP信号,进程只是被停止,再送SIGCONT信号,进程继续运行。 ctrl-d 不是发送信号,而是表示一个特殊的二进制值,表示 EOF 有些信号不能被屏蔽,比如中断,还应该有杀死进程的信号,要不然内核怎么做操作系统中的老大。实际上,SIGKILL和SIGSTOP信号是不能被屏蔽或阻止的,他们的默认动作总是会被执行的。

Ⅷ linux下 如何判断信号量延时

/*编译命令:gcc -o shm shm.c -g */
2
3#include<sys/sem.h>
4#include<sys/ipc.h>
5
6#define SEGSIZE 1024
7#define READTIME 1
8
9union semum
10{
11 int val;
12 struct semid_ds *buf;
13 unsigned short *array;
14}arg;
15
16/* 创建信号量 */
17int sem_creat(key_t key)
18{
19 union semun sem;
20 int semid;
21 sem.val = 0;
22 semid = semget(key, 1, IPC_CREAT | 0666);
23
24 if (semid == -1)
25 {
26 printf("Create semaphore error\n");
27 exit(-1);
28 }
29
30 semctl(semid, 0, SETVAL, sem);
31
32 return semid;
33}
34
35/* 删除信号量*/
36int del_sem(int semid)
37{
38 union semun sem;
39 sem.val = 0;
40 semctl(semid, 0, IPC_RMID, sem);
41}
42
43/* 信号量的P操作,使得信号量的值加1 */
44int p(int semid)
45{
46 struct sembuf sops = {0,
47 +1,
48 IPC_NOWAIT
49 };
50
51 return (semop(semid, &sops, 1));
52}
53
54/* 信号量的v操作,使得信号量的值减1 */
55int v(int semid)
56{
57 struct sembuf sops = {0,
58 -1,
59 IPC_NOWAIT
60 };
61
62 return (semop(semid, &sops, 1));
63}
64
65/* server主程序 */
66int main(int argc, char **argv)
67{
68 key_t key;
69 int shmid, semid;
70 char *shm;
71 char msg[7] = "-data-";
72 char i;
73 struct semid_ds buf;
74
75 key = ftok("/", 0);
76 shmid = shmget(key, SEGSIZE, IPC_CREAT|0604);
77
78 if shmid == -1)
79 {
80 printf(" create shared memory error\n");
81 return -1;
82 }
83
84 shm = (char *)shmat(shmid, 0, 0);
85 if (-1 == (int)shm)
86 {
87 printf(" attach shared memory error\n");
88 return -1;
89 }
90
91 semid = sem_creat(key);
92
93 for (i = 0; i <= 3; i++)
94 {
95 sleep(1);
96 p(semid);
97 sleep(READTIME);
98 msg[5] = '0' + i;
99 memcpy(shm,msg,sizeof(msg));
100 sleep(58);
101 v(semid);
102 }
103
104 shmdt(shm);
105
106 shmctl(shmid,IPC_RMID,&buf);
107
108 del_sem(semid);
109
110 return 0;
111
112}
113
114
115
116
117
118
119
120
121

Ⅸ linux c 信号量与共享内存问题 多客户端同时接受消息

假设服务器的守护进程为D,D维护着一张广播链表。假设链表元素为
struct BEntry{
pid_t pid; //服务器子进程id
mqd_t mqd; //消息队列描述符或者其他IPC手段也可以
};
每次有客户端连上来,做fork的时候就把IPC手段建立好,不管用管道,或者消息,或者共享内存都大同小异,设客户端连上来fork产生的服务器子进程为Subn n为下标。

然后如果要广播消息,就让Subn通知D(可以用广播链表里的IPC手段,也可以另建),然后由D广播消息给各个Subm, Subx,这些Sub进程再发给客户端,这样可以同时广播,效率比较高。

Ⅹ linux常用信号量

  • 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信号来重新启动

热点内容
没有支付密码怎么支付 发布:2024-09-24 21:08:35 浏览:113
海量数据的分布式存储 发布:2024-09-24 21:00:31 浏览:41
思科模拟器反向acl怎么配置 发布:2024-09-24 20:28:41 浏览:765
如何取消文件夹加密 发布:2024-09-24 20:26:30 浏览:668
java中的list 发布:2024-09-24 20:22:10 浏览:765
建飞加密模块 发布:2024-09-24 20:22:09 浏览:247
旅人栈桥服务器怎么样 发布:2024-09-24 20:13:55 浏览:844
vps测试脚本 发布:2024-09-24 20:13:49 浏览:198
ftp使用端口号是 发布:2024-09-24 20:03:07 浏览:972
如何重新配置dp 发布:2024-09-24 19:51:21 浏览:487