You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows平台下lockf()有无替代实现?如何移植对应Linux代码?

Windows平台lockf()函数替代实现与代码移植方案

核心替代逻辑

Windows原生没有POSIX标准的lockf()实现,你代码中用到的lockf(fd, F_LOCK, 0)是阻塞式独占整个文件锁,对应可以使用Win32 API的LockFileEx实现完全对齐的行为。

移植注意事项

  • Windows下POSIX兼容函数的名称前缀为下划线,比如open对应_open、lseek对应_lseek、close对应_close
  • 从C runtime的文件描述符获取Win32原生文件句柄,使用_get_osfhandle()函数
  • LockFileEx默认自动随文件句柄关闭释放锁,和lockf行为一致,无需额外调用解锁接口

适配后的跨平台代码

#include <windows.h>
#include <errno.h>
// 其他原有头文件保持不变

static string load_bulletin_from_file(const char* cache_filename)
{
#ifdef _WIN32
    int fd = _open(cache_filename, _O_RDWR);
#else
    int fd = open(cache_filename, O_RDWR); // lockf requires O_RDWR
#endif
    if (fd == -1) {
        etiLog.level(error) << "TAI-UTC bulletin open cache for reading: " <<
            strerror(errno);
        return "";
    }

#ifdef _WIN32
    _lseek(fd, 0, SEEK_SET);
#else
    lseek(fd, 0, SEEK_SET);
#endif

    vector<char> buf(1024);
    vector<char> new_bulletin_data;

    bool lock_success = false;
#ifdef _WIN32
    HANDLE hFile = (HANDLE)_get_osfhandle(fd);
    if (hFile != INVALID_HANDLE_VALUE) {
        OVERLAPPED ov = {0};
        // 阻塞式独占整个文件锁,和F_LOCK行为完全一致
        if (LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, MAXDWORD, MAXDWORD, &ov)) {
            lock_success = true;
        } else {
            // 把Win32错误转成errno方便统一日志
            errno = EACCES;
        }
    }
#else
    ssize_t ret = lockf(fd, F_LOCK, 0);
    if (ret == 0) {
        lock_success = true;
    }
#endif

    if (lock_success) {
        // exclusive lock acquired
        ssize_t ret;
        do {
#ifdef _WIN32
            ret = _read(fd, buf.data(), buf.size());
#else
            ret = read(fd, buf.data(), buf.size());
#endif

            if (ret == -1) {
#ifdef _WIN32
                _close(fd);
#else
                close(fd);
#endif
                etiLog.level(error) << "TAI-UTC bulletin read cache: " <<
                        strerror(errno);
                return "";
            }

            copy(buf.data(), buf.data() + ret, back_inserter(new_bulletin_data));
        } while (ret > 0);

#ifdef _WIN32
        _close(fd);
#else
        close(fd);
#endif

        return string{new_bulletin_data.data(), new_bulletin_data.size()};
    }
    else {
        etiLog.level(error) <<
            "TAI-UTC bulletin acquire cache lock for reading: " <<
            strerror(errno);
#ifdef _WIN32
        _close(fd);
#else
        close(fd);
#endif
    }
    return "";
}

可选兼容方案

如果你的项目需要更精简的跨平台封装,也可以自己封装一个跨平台的lockf兼容函数,把Windows和POSIX的逻辑隐藏在函数内部,业务代码不需要做大量修改。

内容的提问来源于stack exchange,提问作者Hojzerice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:39:01