http://blog.csdn.net/yongan1006/article/details/6682418
对于linux的程序员来说,信号量是一个不能回避的问题。下面我简要地介绍下信号量在不同状态下的使用。
一,内核态
l 就是写驱动程序时遇到的信号量。
1. 定义信号量
struct semaphore sem;
2. 初始化信号量
void sema_init(struct semaphore *sem,int val);
val是被初始化的信号量的值,一般初始化为0或1。
void init_MUTEX(struct semaphore *sem)等价于sema_init(struct semaphore *sem,1)
void init_MUTEX_LOCKED(struct semaphore *sem)
等价于sema_init(struct semaphore *sem,0)
3. 定义和初始化两项可以合并
DECLEAR_MUTEX(name) DECLEAR_MUTEX_LOCKED(name)
4. 获得信号量
void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);
int down_trylock(struct semaphore *sem);
5. 释放信号量
void up(struct semaphore *sem);
l Linux提供了一种比信号量更好的同步机制,完成量
1.定义 struct completion my_completion;
2.初始化 init_completion(&my_completion)
3.定义和初始化 DECLEAR_COMPLETION(my_completion)
4.等待完成量 void wait_for_completion(struct completion *c);
5.唤醒完成量 void complete(struct completion *c);
void complete_all(struct completion *c);
l 互斥量
定义和初始化
struct mutex my_tex;
mutex_init(&my_tex);
获取互斥量
void fastcall mutex_lock(struct mutex *lock);
int fastcall mutex_lock_interruptible(struct mutex *lock);
int fastcall mutex_trylock(struct mutex *lock);
释放互斥量
void fastcall mutex_unlock(struct mutex *lock);
二,用户态——线程信号量
l 源于POSIX的扩展,信号量函数的名字都以sem_开头。
1.创建并初始化函数
int sem_init(sem_t *sem,int pshared,unsigned int value)
和内核态的信号初始化函数太像了^-^,pshared,一般初始化为0
2.等待信号量
int sem_wait(sem_t *sem)
3.唤醒信号量
int sem_post(sem_t *sem)
4.清理信号量
int sem_destroy(sem_t *sem)
l 互斥量
相关函数
int pthread_mutex_init(pthread_mutex *mutex,const pthread_mutexattr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
三,进程间通信的信号量
该组信号量接口函数源于System V。
这一组接口比前面介绍的使用起来稍复杂一点。
n 定义并获得信号标志符函数
int semget(key_t key,int num_sems,int sem_flags)
信号没有名称,但是有一个semget返回的信号id,用来标志信号。key,可以任意指定。num_sems是需要的信号量的数目,通常为1。sem_flags,由信号量的权限和一些特定意义的宏按位或组成。
例如:sem_id=semget((key_t)1234, 1, 0666 | IPC_CREAT);
n 信号量值行为函数
int semop(int sem_id,struct sembuf *sem_ops,size_t num_sem_ops)
sem_id,是semget调用的返回值
struct sembuf{short sem_num;short sem_op;short sem_flg;}。sem_num,为信号量的编号,sem_op,可以是+1,或-1。+1,代表V操作,-!,代表P操作。flg,一般设置为SEM_UNDO,它的含义是如果这个进程在没有释放使用的信号量的情况下终止,操作系统会去处理释放工作。
num_sem_ops,有几个信号需要这样的操作处理。
例如:struct sembuf sem_b;
sem_b.sem_num=0;
sem_b.sem_op=-1;
sem_b.sem_flg=SEM_UNDO;
if(semop(sem_id,&sem_b,1)==-1)
……
n 信号量值设置与处理函数
int semctl(int sem_id,int sem_num,int command,…)
sem_id,sem_num,与semop函数中的含义相同。
command,要采取的动作。
如果有第4个参数,那么就是
union semun{int val;struct semid_ds *buf;unsigned short *array;}
command有两个常用的命令SETVAL和IPC_RMID
SETVAL, 通过union semun中的val成员,设置sem_id代表的信号的初值
IPC_RMID, 删除不用的信号量标识符sem_id。
例:union semun sem_union;
sem_union.val=1;
semctl(sem_id,0,SETVAL,sem_union);