无法使用多线程读取同一文件

问题描述 投票:0回答:1

我创建了50个线程以同时读取同一文件,然后在每个线程中尝试将其内容写入以不同名称创建的新文件中。该代码应生成50个不同的文件。但是我得到了意想不到的结果,它仅生成3〜5个文件。Results after running my code

当所有人都读取同一个文件时,没有竞争条件,并且每个线程旨在将其内容写入不同的文件。

有人可以帮我吗?谢谢!

下面列出了我的代码,它是对Reference的修改

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include <iostream>
#include <vector>
#include <thread>

void copy(const char *src_path, const char *dst_path);

int main(int argc, char **argv)
{
    std::vector<std::thread> vth;
    char *tmp = "Copy.deb";
    for (int i = 0; i < 50; ++i)
    {
        char src[40];
        memset(src, '\0', sizeof(src));
        sprintf(src, "%d", i);
        strcat(src, tmp);
        vth.emplace_back(std::bind(copy, "Original.deb", strdup(src)));
    }
    for (int i = 0; i < 50; ++i)
    {
        vth[i].join();
    }

    return 0;
}

void copy(const char *src_path, const char *dst_path)
{
    FILE *src, *dst;
    int buffer_size = 8 * 1024;
    char buffer[buffer_size];
    size_t length;

    src = fopen(src_path, "rb");
    dst = fopen(dst_path, "wb");

    while (!feof(src))
    {
        length = fread(buffer, 1, buffer_size, src);
        fwrite(buffer, 1, length, dst);
    }

    fclose(src);
    fclose(dst);
}
c++ multithreading io fopen fread
1个回答
2
投票

[我相信您的问题是,您正在将src(这是指向主线程堆栈上的局部变量的指针)传递给线程的入口函数,但是由于copy()函数在单独的线程中异步运行,因此您要传递指针的char src[40]数组在copy()函数有机会读取其内容之前已经从主线程的堆栈中弹出(并且很可能被其他数据覆盖)。

最简单的解决方法是在堆上复制该字符串,以便可以保证在copy()函数执行并读取之前,该字符串将保持有效:

    vth.emplace_back(std::bind(copy, "Original.deb", strdup(src)));

...,并确保在完成使用copy()函数后释放堆分配:

void copy(const char *src_path, const char *dst_path)
{
  FILE *src, *dst;
  int buffer_size = 8 * 1024;
  char buffer[buffer_size];
  size_t length;

  src = fopen(src_path, "rb");
  dst = fopen(dst_path, "wb");

  free(dst_path);   // free the string previously allocated by strdup()

  [...]

请注意,“ Original.deb”参数目前不存在相同的问题,因为“ Original.deb”是字符串文字,因此静态存储在可执行文件中,这意味着只要程序正在运行-但如果/当您更改代码以不对该参数使用字符串文字时,您可能还需要对其进行类似的操作。

© www.soinside.com 2019 - 2024. All rights reserved.