当前位置: 技术问答>linux和unix
在linux中用C语言编程时怎么实现互斥?
来源: 互联网 发布时间:2015-07-11
本文导语: 我用命名管道编写程序时有多个客户端在向同一个命名管道写,我现在就是想每次只能有一个客户端写这个管道,写完以后服务端读数据,然后另外客户再写,请问怎么实现? | 用信号量实现同步 信号量...
我用命名管道编写程序时有多个客户端在向同一个命名管道写,我现在就是想每次只能有一个客户端写这个管道,写完以后服务端读数据,然后另外客户再写,请问怎么实现?
|
用信号量实现同步
信号量与已经介绍过的I P C机构(管道、F I F O以及消息列队)不同。它是一个计数器,用
于多进程对共享数据对象的存取。为了获得共享资源,进程需要执行下列操作:
(1) 测试控制该资源的信号量。
(2) 若此信号量的值为正,则进程可以使用该资源。进程将信号量值减1,表示它使用了一
个资源单位。
(3) 若此信号量的值为0,则进程进入睡眠状态,直至信号量值大于0。若进程被唤醒后,
它返回至(第( 1 )步)。
当进程不再使用由一个信息量控制的共享资源时,该信号量值增1。如果有进程正在睡眠等待
此信号量,则唤醒它们。
为了正确地实现信息量,信号量值的测试及减1操作应当是原子操作。为此,信号量通常
是在内核中实现的。
常用的信号量形式被称之为双态信号量(binary semaphore)。它控制单个资源,其初始值为1。
但是,一般而言,信号量的初值可以是任一正值,该值说明有多少个共享资源单位可供共享应用。
不幸的是,系统V的信号量与此相比要复杂得多。三种特性造成了这种并非必要的复杂性:
(1) 信号量并非是一个非负值,而必需将信号量定义为含有一个或多个信号量值的集合。
当创建一个信号量时,要指定该集合中的各个值
(2) 创建信息量(s e m g e t)与对其赋初值(s e m c t l)分开。这是一个致命的弱点,因为不能
原子地创建一个信号量集合,并且对该集合中的所有值赋初值。
(3) 即使没有进程正在使用各种形式的系统V IPC,它们仍然是存在的,所以不得不为这种
程序担心,它在终止时并没有释放已经分配给它的信号量。下面将要说明的u n d o功能就是假定
要处理这种情况的。
内核为每个信号量设置了一个s e m i d _ d s结构。
struct semid_ds {
struct ipc_perm sem_perm; /* see Section 14.6.2 */
struct sem *sem_base;/* ptr to first semaphore in set */
ushort s e m _ n s e m s ; /* #of semaphores in set */
time_t s e m _ o t i m e ; /* last-semop() time */
t i m e _ t s e m _ c t i m e ; /* last-change time */
};
对用户而言,s e m _ b a s e指针是没有价值的,它指向内核中的s e m结构数组,该数组中包含
了s e m _ n s e m s个元素,每个元素各对应于集合中的一个信号量值。
3 4 2 U N I X环境高级编程
下载
操作
S PARC,SunOS 4.1.1 8 0 3 8 6 , S V R 4
用户系统时钟用户系统时钟
消息队列0 . 8 1 0 . 7 1 1 . 6 0 . 7 1 9 . 6 2 0 . 1
流管道0 . 3 1 0 . 6 1 1 . 0 0 . 5 2 1 . 4 2 1 . 9
信号量与已经介绍过的I P C机构(管道、F I F O以及消息列队)不同。它是一个计数器,用
于多进程对共享数据对象的存取。为了获得共享资源,进程需要执行下列操作:
(1) 测试控制该资源的信号量。
(2) 若此信号量的值为正,则进程可以使用该资源。进程将信号量值减1,表示它使用了一
个资源单位。
(3) 若此信号量的值为0,则进程进入睡眠状态,直至信号量值大于0。若进程被唤醒后,
它返回至(第( 1 )步)。
当进程不再使用由一个信息量控制的共享资源时,该信号量值增1。如果有进程正在睡眠等待
此信号量,则唤醒它们。
为了正确地实现信息量,信号量值的测试及减1操作应当是原子操作。为此,信号量通常
是在内核中实现的。
常用的信号量形式被称之为双态信号量(binary semaphore)。它控制单个资源,其初始值为1。
但是,一般而言,信号量的初值可以是任一正值,该值说明有多少个共享资源单位可供共享应用。
不幸的是,系统V的信号量与此相比要复杂得多。三种特性造成了这种并非必要的复杂性:
(1) 信号量并非是一个非负值,而必需将信号量定义为含有一个或多个信号量值的集合。
当创建一个信号量时,要指定该集合中的各个值
(2) 创建信息量(s e m g e t)与对其赋初值(s e m c t l)分开。这是一个致命的弱点,因为不能
原子地创建一个信号量集合,并且对该集合中的所有值赋初值。
(3) 即使没有进程正在使用各种形式的系统V IPC,它们仍然是存在的,所以不得不为这种
程序担心,它在终止时并没有释放已经分配给它的信号量。下面将要说明的u n d o功能就是假定
要处理这种情况的。
内核为每个信号量设置了一个s e m i d _ d s结构。
struct semid_ds {
struct ipc_perm sem_perm; /* see Section 14.6.2 */
struct sem *sem_base;/* ptr to first semaphore in set */
ushort s e m _ n s e m s ; /* #of semaphores in set */
time_t s e m _ o t i m e ; /* last-semop() time */
t i m e _ t s e m _ c t i m e ; /* last-change time */
};
对用户而言,s e m _ b a s e指针是没有价值的,它指向内核中的s e m结构数组,该数组中包含
了s e m _ n s e m s个元素,每个元素各对应于集合中的一个信号量值。
3 4 2 U N I X环境高级编程
下载
操作
S PARC,SunOS 4.1.1 8 0 3 8 6 , S V R 4
用户系统时钟用户系统时钟
消息队列0 . 8 1 0 . 7 1 1 . 6 0 . 7 1 9 . 6 2 0 . 1
流管道0 . 3 1 0 . 6 1 1 . 0 0 . 5 2 1 . 4 2 1 . 9
|
《操作系统:设计与实现 上》第二章
|
我想可以设一个全局变里吧·
不过操作系统上确实有很好的方法!去看看先!
不过操作系统上确实有很好的方法!去看看先!
|
那就随便找本操作系统的书,看看同步互斥,信号量之类的。