Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用sendfile()通过线程或其他有效的复制文件方法复制文件_C++_Linux_Multithreading_Sendfile - Fatal编程技术网

C++ 使用sendfile()通过线程或其他有效的复制文件方法复制文件

C++ 使用sendfile()通过线程或其他有效的复制文件方法复制文件,c++,linux,multithreading,sendfile,C++,Linux,Multithreading,Sendfile,我正在尝试使用Linux系统调用sendfile()使用线程复制文件 我对优化代码的以下部分感兴趣: fseek(fin, size * (number) / MAX_THREADS, SEEK_SET); fseek(fout, size * (number) / MAX_THREADS, SEEK_SET); /* ... */ fwrite(buff, 1, len, fout); 代码: void* FileOperate::FileCpThread::threadCp(vo

我正在尝试使用Linux系统调用
sendfile()
使用线程复制文件

我对优化代码的以下部分感兴趣:

fseek(fin, size * (number) / MAX_THREADS, SEEK_SET);  
fseek(fout, size * (number) / MAX_THREADS, SEEK_SET); 
/* ... */
fwrite(buff, 1, len, fout);  
代码:

void* FileOperate::FileCpThread::threadCp(void *param)
{
    Info *ft = (Info *)param;
    FILE *fin = fopen(ft->fromfile, "r+");
    FILE *fout = fopen(ft->tofile, "w+");

    int size = getFileSize(ft->fromfile);

    int number =  ft->num;
    fseek(fin, size * (number) / MAX_THREADS, SEEK_SET);
    fseek(fout, size * (number) / MAX_THREADS, SEEK_SET);

    char buff[1024] = {'\0'};
    int len = 0;
    int total = 0;

    while((len = fread(buff, 1, sizeof(buff), fin)) > 0)
    {
        fwrite(buff, 1, len, fout);
        total += len;

        if(total > size/MAX_THREADS)
        {
            break;
        }
    }

    fclose(fin);
    fclose(fout);
}

文件复制不受CPU限制;如果是这样的话,您可能会发现限制在内核级别,而在用户级别上您所能做的任何事情都不会将其并行化

在机械驱动器上进行的此类“改进”实际上会降低吞吐量。你在浪费时间查找文件,而不是读写它

如果文件很长,并且您不希望很快需要读取或写入的数据,那么在打开时可能会使用
O_DIRECT
标志。这是一个坏主意,因为
O_DIRECT
API本质上是

相反,您应该在源文件和目标文件上使用
posix\u fadvise
,使用posix\u FADV\u顺序和posix\u FADV\u NOREUSE标志。在write(或sendfile)调用完成后,您需要通知不再需要数据-pass POSIX_FADV_DONTNEED。这样,页面缓存将仅在保持数据流动所需的范围内使用,并且一旦数据被消耗(写入磁盘),页面将被回收

sendfile
不会将文件数据推送到用户空间,因此它进一步缓解了来自内存和处理器缓存的一些压力。这是您在复制非特定于设备的文件时可以做的唯一其他明智的改进

选择合理的块大小也是可取的。考虑到现代驱动器的速度超过100兆字节/秒,您可能希望一次推一兆字节,并且总是4096字节页面大小的倍数-因此
(4096*256)
是一个不错的开始块大小,可以在单个
发送文件
读取
/
写入
调用中处理

正如您所建议的,读并行化仅在RAID 0卷上有意义,并且仅当输入和输出文件都跨在物理磁盘上时才有意义。然后,您可以在文件所跨越的源卷和目标卷物理磁盘的数量中,以较小者为单位拥有一个线程。只有在不使用异步文件I/O的情况下才有必要这样做。使用异步I/O,您不需要多个线程,尤其是在块大小较大(兆字节+)且单线程延迟损失可以忽略不计的情况下


在SSD上并行单个文件拷贝没有任何意义,除非您确实在某个非常奇怪的系统上。

文件拷贝不受CPU限制;如果是这样的话,您可能会发现限制在内核级别,而在用户级别上您所能做的任何事情都不会将其并行化

在机械驱动器上进行的此类“改进”实际上会降低吞吐量。你在浪费时间查找文件,而不是读写它

如果文件很长,并且您不希望很快需要读取或写入的数据,那么在打开时可能会使用
O_DIRECT
标志。这是一个坏主意,因为
O_DIRECT
API本质上是

相反,您应该在源文件和目标文件上使用
posix\u fadvise
,使用posix\u FADV\u顺序和posix\u FADV\u NOREUSE标志。在write(或sendfile)调用完成后,您需要通知不再需要数据-pass POSIX_FADV_DONTNEED。这样,页面缓存将仅在保持数据流动所需的范围内使用,并且一旦数据被消耗(写入磁盘),页面将被回收

sendfile
不会将文件数据推送到用户空间,因此它进一步缓解了来自内存和处理器缓存的一些压力。这是您在复制非特定于设备的文件时可以做的唯一其他明智的改进

选择合理的块大小也是可取的。考虑到现代驱动器的速度超过100兆字节/秒,您可能希望一次推一兆字节,并且总是4096字节页面大小的倍数-因此
(4096*256)
是一个不错的开始块大小,可以在单个
发送文件
读取
/
写入
调用中处理

正如您所建议的,读并行化仅在RAID 0卷上有意义,并且仅当输入和输出文件都跨在物理磁盘上时才有意义。然后,您可以在文件所跨越的源卷和目标卷物理磁盘的数量中,以较小者为单位拥有一个线程。只有在不使用异步文件I/O的情况下才有必要这样做。使用异步I/O,您不需要多个线程,尤其是在块大小较大(兆字节+)且单线程延迟损失可以忽略不计的情况下


在SSD上并行单个文件拷贝没有任何意义,除非您确实在某个非常奇怪的系统上。

文件拷贝不受CPU限制;如果是这样的话,您可能会发现限制在内核级别,而在用户级别上您所能做的任何事情都不会将其并行化

在机械驱动器上进行的此类“改进”实际上会降低吞吐量。你在浪费时间查找文件,而不是读写它

如果文件很长,并且您不希望很快需要读取或写入的数据,那么在打开时可能会使用
O_DIRECT
标志。这是一个坏主意,因为
O_DIRECT
API本质上是

相反,您应该在源文件和目标文件上使用
posix\u fadvise
,使用posix\u FADV\u顺序和posix\u FADV\u NOREUSE标志。在write(或sendfile)调用完成后,您需要通知不再需要数据-pass POSIX_FADV_DONTNEED。这样,页面缓存将仅在保持数据流动所需的范围内使用,并且一旦数据被消耗(写入磁盘),页面将被回收

sendfile
不会将文件数据推送到用户spa