Chinaunix首页 | 论坛 | 博客
  • 博客访问: 993268
  • 博文数量: 200
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 2479
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-27 15:07
文章分类

全部博文(200)

文章存档

2009年(12)

2008年(190)

我的朋友

分类:

2008-11-07 16:20:41

1. record locking 可以保证多个process对同一数据访问的安全性,注意是多个进程之间的互斥
2. 在同一个进程里,如果获得了对一个文件的锁,那么后续再次加锁的动作是可以的:
    (1)如果在同一range加锁,那么新锁会replace旧锁
    (2)如果range不同,那么会一举各个range是否有交集及并集进行相应的锁的改变
3. 如果若干个进程同时申请了对一个range的读锁,而且不断有新的进程来申请读锁,那么有可能旁边一个等待获得写锁的进程始终得不到许可,产生饥饿
4. 死锁也是可以的,例子:
Figure 14.7. Example of deadlock detection
#include "apue.h"
#include

static void
lockabyte(const char *name, int fd, off_t offset)
{
if (writew_lock(fd, offset, SEEK_SET, 1) < 0)
err_sys("%s: writew_lock error", name);
printf("%s: got the lock, byte %ld\n", name, offset);
}

int
main(void)
{
int fd;
pid_t pid;

/*
* Create a file and write two bytes to it.
*/
if ((fd = creat("templock", FILE_MODE)) < 0)
err_sys("creat error");
if (write(fd, "ab", 2) != 2)
err_sys("write error");

TELL_WAIT();
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
lockabyte("child", fd, 0);
TELL_PARENT(getppid());
WAIT_PARENT();
lockabyte("child", fd, 1);
} else { /* parent */
lockabyte("parent", fd, 1);
TELL_CHILD(pid);
WAIT_CHILD();
lockabyte("parent", fd, 0);
}
exit(0);
}

5. 一个process里,一个文件的某一个descriptor(注意在一个process里,
有可能有多个descriptor对应同一个文件,如通过dup,dup2或者多次open)被关闭,那么该进程针对该文件
的所有的lock都会被释放,而不管究竟这些lock当初建立的时候是使用了那个descriptor。因为kernel纪录
文检锁的方法是在v-node里建立一个lock-list,每个list-item记载的只有进程id,以及区域和锁类型,没有纪录
descriptor。
可见,process table entry里记载了file descriptor,并且指向了对应的file table entry,dup调用会产生
新的descriptor,但是他们共同指向相同的file table entry。 再次open同一个文件会产生新的descriptor和新的
file table entry,但是他们和以前的file table entry最终指向了同一个v-node。即他们还是指向同一个文件。那么
此时,只要有一个descriptor被关闭,那么该文件上所有的lock都被remove。

6. 由5知道,当程序退出的时候,所有descriptor关闭,那么锁会自动释放。
7. 子进程会继承父进程的descriptor以及,并且与父进程指向相同的file table entry,但是子进程不会继承父进程
的lock,因为这样就乱了。那么如果子进程要想加锁,就得自己从新来过,而且子进程关闭该descriptor不会影响夫进程
里面的锁。
8. 进程执行exec时,会保留descriptor,从而也保留文件锁,但是前提是该descriptor没有被设置close-on-exec标记,因为
这个标记会使该文件在进程调用exec时被关闭,从而其上的锁也会被释放。
9. advisory and mandatory locking
所谓advisory的意思是说我们的程序,如果你们都是用锁机制,那么好一且正常,如果有些家或不用锁机制,直接读写
文件,那么我们也拿他没办法,文件会被弄坏。没有办法。
所谓mandatory意思是说,好了,我们现在有办法了,就算你不才用锁机制直接读写,我也会首先作出检查,看是否
有别的进程已经加了锁,如果是,那么好了你能否成功操作就要一举一定的rule了,这就是强制性的机制。
当然这建立在对open, read, write等函数的检查的基础上。但是有的实现,绕开了这些函数,而使用了unlink,尽管
该文件被加了读锁,但是人家虽然不能直接写,人家可以读出你的内容,然后对你unlink,然后人家新生成一个别的名字的文件,写完后,
等你加锁的进程完了,你这个文件也自动被remove了(前提是unlink将其最后一个link去掉了),人间再将新文件rename
成这个文件,也达到了同样的效果。

#include 

int fcntl(int filedes, int cmd, ... /* struct
flock *flockptr */ );

Returns: depends on cmd if OK (see following), 1 on error


struct flock {
short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
off_t l_start; /* offset in bytes, relative to l_whence */
short l_whence; /* SEEK_SET, SEEK_CUR, or SEEK_END */
off_t l_len; /* length, in bytes; 0 means lock to EOF */
pid_t l_pid; /* returned with F_GETLK */
};
fcntl 的cmd有如下几种:

F_GETLK

Determine whether the lock described by flockptr is blocked by some other lock. If a lock exists that would prevent ours from being created, the information on that existing lock overwrites the information pointed to by flockptr. If no lock exists that would prevent ours from being created, the structure pointed to by flockptr is left unchanged except for the l_type member, which is set to F_UNLCK.

F_SETLK

Set the lock described by flockptr. If we are trying to obtain a read lock (l_type of F_RDLCK) or a write lock (l_type of F_WRLCK) and the compatibility rule prevents the system from giving us the lock (), fcntl returns immediately with errno set to either EACCES or EAGAIN.

Although POSIX allows an implementation to return either error code, all four implementations described in this text return EAGAIN if the locking request cannot be satisfied.

This command is also used to clear the lock described by flockptr (l_type of F_UNLCK).

F_SETLKW

This command is a blocking version of F_SETLK. (The W in the command name means wait.) If the requested read lock or write lock cannot be granted because another process currently has some part of the requested region locked, the calling process is put to sleep. The process wakes up either when the lock becomes available or when interrupted by a signal.



阅读(656) | 评论(0) | 转发(0) |
0

上一篇:_T("string") macro

下一篇:ssh tunnels

给主人留下些什么吧!~~