- 论坛徽章:
- 0
|
10可用积分
[本问题已解决]
经过timespace的提醒,使用sigaction替代signal来注册SIGARLM,使得fcntl被信号中断以后得以重启(SA_RESTART),代码如下
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<errno.h>
#include<string.h>
#include<signal.h>
extern int errno;
extern "C" void s(int sig,siginfo_t *, void *){
printf("signal handle: %d\n",sig);
}
int main(void){
int fdes=open("kg",O_RDWR|O_CREAT,0664);
if(fdes<0){
printf("open fail\n");
exit(1);
}
struct sigaction act,oact;
sigemptyset(&act.sa_mask);
act.sa_sigaction=s;
act.sa_flags=SA_RESTART;
sigaction(SIGALRM,&act,&oact);
struct flock lock;
lock.l_type=F_WRLCK;
lock.l_start=0;
lock.l_whence=SEEK_SET;
lock.l_len=0;
alarm(5);
if(fcntl(fdes,F_SETLKW,&lock)==-1){
alarm(0);
printf("error=%d,%s\n",errno,strerror(errno));
close(fdes);
exit(1);
}
printf("lock got\n");
signal(SIGALRM,SIG_IGN);
sleep(60);
close(fdes);
return 0;
}
现在两个进程能同时运行,不会出现system call interrupted了! 分送出!
-------------------------------------------------------------------------
在一台Solaris的工作站遇到一个问题
int fdes = open(path,O_RDWR|O_CREAT,0664);
if(fcntl(fdes,F_SETLKW,&lock) == -1){
printf("%d text: %s\n",lerrno,strerror(lerrno));
}
...
...
这段程序遇到了错误,打印:
4 text: Interrupted system call
我查了一下手册:
F_SETLKW:行为如同F_SETLK,除了不能获取锁时会睡眠等待外。如果在等待的过程中接收到信号,会立即返回并将errno置为EINTR
我把问题提取出来了,形成一个小程序:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<errno.h>
#include<string.h>
#include<signal.h>
extern int errno;
extern "C" void s(int sig){
printf("signal handle: %d\n",sig);
}
int main(void){
int fdes=open("kg",O_RDWR|O_CREAT,0664);
if(fdes<0){
printf("open fail\n");
exit(1);
}
signal(SIGALRM,&s);
struct flock lock;
lock.l_type=F_WRLCK;
lock.l_start=0;
lock.l_whence=SEEK_SET;
lock.l_len=0;
alarm(5);
if(fcntl(fdes,F_SETLKW,&lock)==-1){
signal(SIGALRM,SIG_IGN);
alarm(0);
printf("error=%d,%s\n",errno,strerror(errno));
close(fdes);
exit(1);
}
printf("lock got\n");
signal(SIGALRM,SIG_IGN);
sleep(20);
close(fdes);
return 0;
}
(1)编译运行:
一个term里面./a.out (称为进程a)
另一个term里面也瞬间./a.out (称为进程b)
(2)运行结果:
a进程运行以后对文件加锁,打印"lock got",然后睡20s,结束
b进程启动以后fcntl会等待(因为F_SETLKW),然后第5s的时候,进程接受到了SIGALRM,(因为alarm(5)的原因,然后打印
signal handle: 14
error=4,Interrupted system call
(3)问题是:
a进程为什么没有执行信号处理函数s从而打印出"signal handle: 14"
b进程的信号处理函数已经起了作用,为什么fcntl(fdes,F_SETLKW,&lock)仍然被信号中断?
测试环境: solaris8+CC
谢谢!!!!!
请问: fcntl加文件锁,什么时候会接收到信号呢? 每次运行到这里都失败。
谢谢!!!!!!
[ 本帖最后由 jeanlove 于 2009-4-8 17:11 编辑 ] |
|