曹洪建 發表於 2024-4-3 11:36:20

rust 如何使用文件锁防止应用多开

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>安装依赖</li><li>使用方法</li><li>库支持的系统</li><li>原理简介</li><ul class="second_class_ul"><li>1. 锁操作</li><ul class="third_class_ul"><li>linux</li><li>windows</li></ul><li>2. 进程退出解锁清空文件内容</li><ul class="third_class_ul"></ul></ul></ul></div><p>本文给出了进程只能单开的方法。</p>
<p class="maodian"></p><h2>安装依赖</h2>
<div class="jb51code"><pre class="brush:bash;">cargo add fslock</pre></div>
<p class="maodian"></p><h2>使用方法</h2>
<div class="jb51code"><pre class="brush:plain;">use fslock::LockFile;
// 打开pid文件,没有则自动创建
let mut pid_lock =
      LockFile::open(&amp;pid_path.clone().into_os_string()).unwrap();
// 非阻塞的锁文件
if !pid_lock.try_lock_with_pid().unwrap() {
    // 如果文件已经被锁,则退出进程
    // ...
}
// 文件加锁成功,则执行业务逻辑
// ...</pre></div>
<p class="maodian"></p><h2>库支持的系统</h2>
<p>此库支持 <code>windows</code>、<code>linux</code> 和 <code>mac</code>,通过如下代码实现</p>
<div class="jb51code"><pre class="brush:plain;">#
mod unix;
#
use crate::unix as sys;
mod string;
mod fmt;
#
mod windows;
#
use crate::windows as sys;</pre></div>
<p class="maodian"></p><h2>原理简介</h2>
<p class="maodian"></p><h3>1. 锁操作</h3>
<p class="maodian"></p><h4>linux</h4>
<p>调用 libc.so的接口实现,目的是不使用 <code>std</code> 库。</p>
<div class="jb51code"><pre class="brush:plain;">pub fn try_lock(fd: FileDesc) -&gt; Result&lt;bool, Error&gt; {
    let res = unsafe { libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB) };
    if res &gt;= 0 {
      Ok(true)
    } else {
      let err = errno();
      if err == libc::EWOULDBLOCK || err == libc::EINTR {
            Ok(false)
      } else {
            Err(Error::from_raw_os_error(err as i32))
      }
    }
}</pre></div>
<p class="maodian"></p><h4>windows</h4>
<div class="jb51code"><pre class="brush:plain;">pub fn try_lock(handle: FileDesc) -&gt; Result&lt;bool, Error&gt; {
    let mut overlapped = make_overlapped()?;
    let drop_handle = DropHandle { handle: overlapped.hEvent };
    let res = unsafe {
      LockFileEx(
            handle,
            LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
            0,
            1,
            1,
            &amp;mut overlapped as LPOVERLAPPED,
      )
    };
    let ret = if res == TRUE {
      let res = unsafe { WaitForSingleObject(overlapped.hEvent, 0) };
      if res != WAIT_FAILED {
            Ok(true)
      } else {
            Err(Error::last_os_error())
      }
    } else {
      let err = unsafe { GetLastError() };
      if err == ERROR_LOCK_VIOLATION {
            Ok(false)
      } else {
            Err(Error::from_raw_os_error(err as i32))
      }
    };
    drop(drop_handle);
    ret
}</pre></div>
<p class="maodian"></p><h3>2. 进程退出解锁清空文件内容</h3>
<div class="jb51code"><pre class="brush:plain;">impl Drop for LockFile {
    fn drop(&amp;mut self) {
      if self.locked {
            let _ = self.unlock();
      }
      sys::close(self.desc);
    }
}
    pub fn unlock(&amp;mut self) -&gt; Result&lt;(), sys::Error&gt; {
      if !self.locked {
            panic!("Attempted to unlock already unlocked lockfile");
      }
      self.locked = false;
      sys::unlock(self.desc)?;
      // 解锁后清空文件内容
      sys::truncate(self.desc)?;
      Ok(())
    }</pre></div>
<p>到此这篇关于rust 如何使用文件锁防止应用多开的文章就介绍到这了,更多相关rust 文件锁内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Rust读取配置文件的实现步骤</li><li>rust文件读写的实现示例</li><li>Rust&nbsp;配置文件内容及使用全面讲解</li><li>如何使用bindgen将C语言头文件转换为Rust接口代码</li><li>Rust 中的文件操作示例详解</li><li>rust延迟5秒锁屏的实现代码</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: rust 如何使用文件锁防止应用多开