- 论坛徽章:
- 0
|
写这篇文章完全出于偶然。缘由是我在记录锁的时候想测试一下当对同一块文件区域加不允许的锁时,errno的值到底是什么!结果编了一个让自己郁闷了一上午的程序,中午吃饭回来也不知所以然。索性不想了,看了一会儿体育新闻。期间上了趟厕所,没事儿做就又开始想上午的那个问题, 慢慢理了一下头绪。万了又在机子上试了一下,成了。
虽然是个小问题,但是觉得里边有些概念确实很关键,也是初学者容易犯错误的地方.所以写下来给自己长个记性.
记录锁,用来在当一个进程正在读或修改文件的某个部分时,可以阻止其他进程(如果是本进程的话那么fcntl函数对该区域重新加锁)修改同一文件区。
记录锁又分为读锁和写锁。当一个进程对某一个块区域设定读锁时,其他进程只能在这块区域内加读锁而不能加写锁; 当某一个进程对文件的某一块区域设定为写锁时,那么其他进程对这块区域不能加任何锁(读锁或写锁)。
当进程终止时,它建立的锁都被释放掉(我所遇到的问题!).
在POSIX.1中使用了fcntl函数和flock结构体来对文件区域加锁。
#include stdio.h>
#include fcntl.h>
#include unistd.h>
#include sys/types.h>
#include sys/stat.h>
#include errno.h>
int set_lock(int, short, off_t, short, off_t);
int
main(void)
{
int fd;
pid_t pid;
if((fd = open("tmp.file", O_RDWR | O_CREAT, 0664)) 0) {
printf("error open\n");
exit(1);
}
if(write(fd, "hello world!", 12) != 12) {
printf("write error\n");
exit(1);
}
if((pid = fork()) 0) {
printf("fork error\n");
exit(1);
} if(pid == 0) {
//sleep(5);
printf("before\n");
if( (tmp = set_lock(fd, F_WRLCK, 0, SEEK_SET, 12)) 0)
printf("errno1 = %d\n", errno);
/*关键,如果没有这个函数的话,子进程会终止掉,随着子进程 *的终止,子进程所加的锁也就自动解锁. 那么永远都不会发生加锁冲突, *errno 的值也会一直是0.
*/
pause();
} else if(pid > 0){
if(set_lock(fd, F_WRLCK, 3, SEEK_SET, 8) 0)
printf("errno2 = %d\n", errno);
pause(); //同上
}
exit(0);
}
///////////////////////
int
set_lock(int fd, short type, off_t start, short whence, off_t len)
{
struct flock locktmpbuf;
locktmpbuf.l_type = type;
locktmpbuf.l_start = start;
locktmpbuf.l_whence = whence;
locktmpbuf.l_len = len;
return(fcntl(fd, F_SETLK, &locktmpbuf));
}
后记, 说来有意思, 想了一上午,没想通. 去了趟厕所...! :)
收获大于我的付出!
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/26820/showart_211154.html |
|