记录锁:
fcntl(int fd,int cmd,struct flock *flockptr)
cmd:F_GETLK
F_SETLK 非阻塞,失败时会立即返回,并设置errno为EACCES EAGAIN
F_SETLKW 阻塞式,会在可加锁时返回或者由信号中断
记录锁的继承和释放:
1、进程终止时,释放所有锁
2、进程对文件F设置了锁,那么该进程中任何一个打开了文件F的文件描述符被关闭,都会释放进程对文件F设置的锁
3、fork后子进程不会继承父进程的锁
4、如果文件描述符标志位(执行时关闭标志位)没有被设置,那么调用exec后,新的程序继承文件锁,否则,释放所有锁
struct flock
{
short l_type /*F_RDLCK F_WRLCK F_UNLOCK*/
short l_whence //SEEK_SET SEEK_CUR SEEK_END
off_t start
off_t len
pid_t pid //持有锁的进程ID
}
在文件尾加锁时,会对新写入的数据也加锁,这时要解锁的话,要SEEK到加锁之前的pos;
建议锁和强制锁
http://blog.sina.com.cn/s/blog_779fba530100ugrd.html
1、
2、
强制锁会导致带有O_TRUNC的open函数失败,erron设置为EAGAIN
如果使用ed编辑带有强制锁的文件,会绕过强制锁(ed会删除原来的文件,将临时文件改为源文件),强制锁对unlink没有影响
使强制锁起作用:
1、mount -o mand
2、打开设置组id,关闭组执行位
I/O多路转接
select(int maxfdpl,fd_set *restrict readfds,fd_set *restrict writefds,fd_set *restrict exceptfds,struct timeval *restrict tvptr)
构造一张由读文件描述符集readfds、写文件描述符集writefds和异常条件集exceptfds构成的表,当其中有一个文件描述符准备好时(可以无阻塞的进行读、写操作)或者异常条件中有一个未决异常条件,select函数返回正值,表示三个描述符中准备好的个数,并修改三个文件描述符集,这时仍存在于描述符集中的fd就是已准备好的
返回0表示在tvptr指定的时间内没有文件描述符准备好,tvptr=NULL表示无超时,即永远阻塞,tvptr->tv_sec==0&&tvptr->tv_usec==0,表示不阻塞,else,表示阻塞到tvptr所指定的时间
返回-1表示出错返回,在没有文件描述符准备好的情况下被信号中断。
maxfdpl是三个文件描述符集中最大的文件描述符的值+1
pselect将timeval改为timespec(usec->nsec),并增加了一个信号屏蔽字参数
文件描述符集的设置函数:
int FD_ISSET(int fd,fd_set *fdset)//fd是否为fd_set的成员
void FD_CLR(int fd,fd_set *fdset)//在fdset中清楚fd
void FD_SET//在fdset中添加fd
void FD_ZERO(fdset) //清空fdset
poll(struct pollfd fdarray[],nfds_t nfds,int timeout)
select函数的文件描述符是按功能分成一个集合,而poll是一个文件描述符数组struct pollfd fdarray[],包含了nfds个文件描述符,并对每个文件描述符的读写异常进行设置
struct pollfd
{
int fd;
short events; //设置对该文件描述符所关心的事件
short revents; //poll函数返回时由内核设置,表示发生了什么事件
}