|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
为保证每个线程对同一资源访问有效,比如一个线程想要从共享资源读数据,而这些资源正在被其他线程修改,那么读出来的数据是无效的,那么就要想办法让其他线程修改完再去读,这时候就用到了同步机制。可以使用Linux系统提供的机制来对线程访问资源的顺序进行同步,本文档挑选了信号量,互斥锁,条件变量来介绍线程同步机制,实验代码在sync/目录下。
1 w6 s9 M2 ?# F7 `9 a8 ^5 o' G- i, o0 p' y: l& O1 K0 a4 N7 @# X
1 POSIX无名信号量
) O( T! S1 S: [本章介绍POSIX 无名信号量,以下简称信号量。信号量类似于计数器,操作方法和前面的System V 信号灯基本一样。
$ {) i2 ^1 C! d6 [9 @6 j r2 Z使用信号量的步骤: d: A: i- h+ |' G; l$ d3 [
1.在程序全局区定义信号量;
9 ~% ]& [7 R* t. S" j. [5 @2.使用seminit()初始化信号量;
; T2 i8 \; _( ?( e3.使用sem_wait()和sem_post()对信号量进行P/V操作;9 z) |" l ]4 k; k/ V% M
4.使用sem_destroy()销毁信号量。
- }# e8 ~8 |' w+ S$ n9 J
1 r# C- B" w. k1 M9 \: N! u0 M8 Q信号量常用函数如下:
$ X( }; S5 q6 \sem_init():对信号量值进行初始化,
) [3 Y6 b* n: A0 g1 b. j#include
$ w( ?; ^+ |9 Z$ f7 [int sem_init(sem_t *sem, int pshared, unsigned int value);
$ G" Y7 s" n1 ~0 w' e; p6 \参数含义:" a/ a8 N( \5 d
sem:指针,指向定义的信号量;
* c2 a8 u. c2 a% V2 wpshared:指明这个信号量用于进程还是线程,0为线程,不等于0为进程,本节填写为0。
3 t2 F: [1 N5 H' k+ ~# s# ?; @value:信号量初始值' m9 M' _# O* }
返回值:成功返回0,错误返回-1。) s8 y: }: v4 _, D5 Y9 S( |$ x. d
3 ~, G% f2 B& ^8 c
sem_wait():等待一个信号量,进行P操作,信号量值-1;. H' d! h1 ]$ I O+ z
sem_post():唤醒一个信号量,进行V操作,信号量值+1,定义如下:* Q0 b. o6 o2 J- A* W4 f; u
#include
, Q- T& g! m# P4 U( N" @: ^7 C' E. rint sem_wait(sem_t *sem);8 `& r; v, I$ v% i
int sem_post(sem_t *sem);1 \3 D- z }& z
参数含义:7 r3 v }+ ?. M; _; U! O: _0 ?' A
sem:要操作的信号量;) y+ [3 t9 B1 Z1 l
返回值:成功返回0,错误返回-1。
7 h! ]! ^+ [: {, | f( e5 \5 L- }- M" k5 O" V$ C8 k) N
sem_destroy():销毁初始化后的信号量& e6 J9 J0 @" g6 i; s$ h9 Q7 e( J
#include- F* I. {) Z: \$ v
int sem_destroy(sem_t *sem);7 b; ^4 |- d% w, ?( K
sem:要操作的信号量;3 [1 ?8 {8 j/ T; u
返回值:成功返回0,错误返回-1。4 h: D! {$ k7 K! E2 m
3 Z% j7 {' O5 y实验代码在sync/sem.c:路径为:11_Linux系统开发进阶\Linux系统编程_章节使用资料。
& h: }9 w L# o% Y: k% Y使用信号量控制读写线程,初始化时写信号量为1,读信号量为0,那么读线程就会阻塞,写线程就会执行并将写信号-1,写线程在fgets等待输入,当输入完成后,将读信号+1唤醒读线程,这样读写线程交替执行就完成了同步。5 ]# L3 w4 {% I1 N3 r! S6 p/ g
![]()
7 x& e+ \0 \' t; x( A& j% E3 P / q) r" Z. H9 g
& A- Y7 @2 E" y. d![]()
j7 m2 t4 r$ R2 Q0 I" _0 {, n! h2 {: C* g% w3 _! x! I. \
|
|