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

多线程场景下用多文件流读取文件时fseek失败的原因

问题

问题背景

我有一个结构独特的大型二进制文件,其中的数据单元称为“event”。每个event占32016字节,单个文件约包含400000个event,文件大小约12GB。我正在编写程序处理这些event,尝试采用多线程方案,让每个线程使用独立的文件流读取文件的不同段。

问题现象

fseek函数无法定位到文件的正确位置。以下是最小复现代码(当前为单线程,后续会扩展为多线程),程序读取包含473797个event的二进制文件,计划使用20个线程,每个线程对应一个独立文件流:

#include <iostream>
#include <stream>
#include <errno.h>
#include <string.h>

using namespace std;

int main(){

        FILE *segment[20];
        int ret=0;
        int eventsPerThread=473797/20;
        int eventSize=8004;
        for(int k=0;k<20;++k){
                segment[k]=fopen("Datafile_367.bin","rb");
                if(segment[k]==NULL){
                        std::cout<<"file stream is NULL!"<<k<<"\n";

                }

                ret=fseek(segment[k],eventsPerThread*eventSize*4*k,SEEK_SET);
                std::cout<<ret<<":::"<<strerror(errno)<<"\n";


        }
                return 0;
}

程序输出如下,fseek有时成功返回0,有时失败返回-1,错误码为22(Invalid argument):

0:::Success
0:::Success
0:::Success
-1:::Invalid argument
-1:::Invalid argument
-1:::Invalid argument
0:::Invalid argument
0:::Invalid argument
0:::Invalid argument
-1:::Invalid argument
-1:::Invalid argument
-1:::Invalid argument
0:::Invalid argument
0:::Invalid argument
0:::Invalid argument
-1:::Invalid argument
-1:::Invalid argument
0:::Invalid argument
0:::Invalid argument
0:::Invalid argument

请问出现这种fseek函数行为的原因是什么?


原因分析

你的问题出在偏移量计算时的整数溢出:

  • 你用int类型存储偏移量的计算结果,但eventsPerThread * eventSize * 4 * k的数值会远超过32位int的最大值(2147483647)。比如当k=19时,计算结果为23689 * 8004 * 4 * 19 ≈ 14.3GB,这个数值远大于int能容纳的范围,会触发整数溢出,得到一个无效的负数或乱码值。
  • fseek的第二个参数offset在标准C中是long类型(64位系统下通常为64位,32位系统下为32位),当你传入溢出后的无效int值时,就会触发"Invalid argument"错误。

修复方法

  • 将偏移量计算的变量改为long long类型,确保计算过程中不会溢出:
    long long offset = (long long)eventsPerThread * eventSize * 4 * k;
    ret = fseek(segment[k], offset, SEEK_SET);
    
  • 同时建议将eventsPerThread、eventSize这类变量改用更大的整数类型(比如long)存储,避免中间计算步骤发生溢出。

另外注意代码中的一个小错误:头文件应该是<fstream>而非<stream>,不过这不是fseek失败的直接原因。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 21:05:09