项目中有个功能会占用本地的代理服务器,当系统中已有进程时,就会导致新运行的进程创建的代理服务器失效。当然,正常情况下,Mac系统不会因为你点击了APP就会有多个进程,BUT,总会意外,比如你更改了你的应用版本 Or 其他我也不知道的原因。
废话不多说了吧,先来介绍下文件锁
fcntl 文件锁(功能强大,有兴趣可以单独去了解,小白作者也是瞎比比)
当我们有多个进程想要访问同一个文件时,为了避免读写冲突,就需要对文件上锁。同理可得,如果一个文件上锁了,说明我的应用已经打开了,所以就不能再运行了。。。
int fcntl(int,int, ...)
fcntl拥有多个可变参数,能够对文件的某一部分进行上锁。第一个参数是要操作的文件的描述符;第二个参数是cmd操作,只能是F_GETLK, F_SETLK, 或者 F_SETLKW;第三个是一个指向flock结构体的指针。
struct flock {
off_t l_start; /* starting offset */
off_t l_len; /* len = 0 means until end of file */
pid_t l_pid; /* lock owner */
short l_type; /* lock type: read/write, etc. */
short l_whence; /* type of l_start */
};
苹果的文档中对几个参数描述的还可以,看不懂Google下就好了。简单来说pid不用传,别的参数挨个给就好了,毕竟我们只是需要上锁,其他的不用考虑。
具体实现:
- (BOOL)checkIsLocked{
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *filPath = [bundlePath stringByAppendingPathComponent:@"CSLockFile"];
int fd = 0;
fd = open(filPath.UTF8String, O_RDWR | O_CREAT);
if (fd < 0) {
[self macAlert:@"Application is running"];
return 1;
}
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_len = 0;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
//if wrong ,all return -1
if (fcntl(fd, F_SETLK, &fl) == -1) {
if (errno == EACCES || errno == EAGAIN) {
close(fd);
return 1;
}
return 1;
}
ftruncate(fd, 0);
return 0;
}
网友评论