在Unix的System V中,Unix信号量通常被认为是对资源的访问,因此资源可用则用正整数表示,当资源被全部占用,则为零。资源共享是UNIX多用户系统的一个重要特征,Unix信号量(SEMAPHORE)则是防止两个或多个进程同时访问共享资源的一种机制。在Unix信号量机制实现之前,通常采用加锁文件的方法,其算法描述如下:
⑴加锁算法
- int lock(lockfile)
- /*返回值0代表成功,其它为失败*/
- char *lockfile; /*加锁文件名*/
- {
- intfd,ret=0;
- extern int errno;
- if((fd=open(lockfile,O_WRONLY|O_CREAT|O_EXCL,0666))==-1
- &&errno==EEXIST) ret=1;
- return(ret);
- }
⑵解锁算法
- unlock(lockfile)
- char *lockfile; /*锁文件名*/
- {
- unlink(lockfile);
- }
这种方法对访问共享资源次数较少的进程是可行的,但对重载的使用则开销太大了,况且一旦加锁失败则进程不知何时可以再试;当系统崩溃或重启动时,加锁文件可能会被忘掉了。
Dijkstra发表的Dekker算法给出了Unix信号量的一种实现,为整值对象定义了两个了原语操作:P和V。其C描述如下:
- void P(sem)
- int *sem;
- {
- while (*sem<=0);
- (*sem)--;
- }
- void V(sem)
- int *sem;
- {
- (*sem)++;
- }
但上述算法不能在用户空间编程,因为①sem指向的Unix信号量变量不能在进程间共享,它们有自己的数据段;②函数非原子执行,内核可在任何时候中断一个进程;③若sem为0,进程并不释放CPU。
所以Unix信号量必须由内核提供,它可在进程间共享数据,可执行原子操作(即一组操作要么全部执行,要么都不执行),可在一个进程阻塞时将CPU给另外一个进程。 这次关于Unix信号量的知识就先做个简单的介绍。
【编辑推荐】