Kushal Bhattacharya
Kushal Bhattacharya

Reputation: 33

How can I pass an ifstream as argument to std::thread function?

I did some research googling regarding the usage of std::ifstream within a thread as function argument, but managed to find its C implementation in pthread. What I want is for it to be implemented in C++11, as I am using standard C++ threads.

I am trying to pass a std::ifstream as argument to thread, but I get the following error:

error: no type named type in class std::result_of<void (*(std::basic_ifstream<char>))(std::basic_ifstream<char>)>
typedef typename result_of<_Callable(_Args...)>::type result_type;

How do I pass the ifstream argument to the function being called on thread? Here's my code:

#include <cstdlib>
#include <fstream>
#include <thread>
#include <iostream>
using namespace std;

void file_func_1(std::ifstream m_file)
{
    // ifstream m_file;
    string line;
    while (getline(m_file, line)) {
        cout << "the line now in is" << line
             << "from thread" << std::this_thread::get_id()
             << endl;
        std::this_thread::sleep_for(std::chrono::seconds((rand() % 10) + 1));
    }
}

void file_func_2(ifstream m_file)
{
    string line;
    while (getline(m_file, line)) {
        cout << "the line now in is" << line
             << "from thread" << std::this_thread::get_id()
             << endl;
        std::this_thread::sleep_for(std::chrono::seconds((rand() % 10) + 1));
    }
}

int main(int argc, char** argv)
{
    std::ifstream m_file;
    m_file.open("File_line.txt", ios::in);
    int name=8;
    std::thread func_th1(file_func_1, (m_file));
    // thread func_th2(file_func_2,m_file);
    func_th1.join();
    // func_th2.join();
    return 0;
}

Upvotes: 1

Views: 2732

Answers (1)

IanM_Matrix1
IanM_Matrix1

Reputation: 1594

You have two issues here. The first is that you can't pass streams by value, you need to pass them by reference.

Second, it appears that you can't pass a stream via a thread directly (although there are probably work-arounds [EDIT: std::ref appears to work, despite comments - maybe it's a version issue as I'm using g++ with c++1z] ).

So, make your functions access references, and call your functions using a lambda when creating the thread:

#include <cstdlib>
#include <fstream>
#include <thread>
#include <iostream>
#include <functional>

using namespace std;

void file_func_1(std::ifstream &m_file){
    string line;
    while ( getline (m_file,line) ){
        cout<<"the line now in is"<<line<<"from thread"<<std::this_thread::get_id()<<endl;
        std::this_thread::sleep_for(std::chrono::seconds((rand() % 10) + 1));
    }
}

int main(int argc, char** argv) {
    std::ifstream m_file;
    m_file.open("File_line.txt",ios::in);
    int name=8;
    std::thread func_th1([&m_file]() { file_func_1(m_file); });
    std::thread func_th2(file_func_1, ref(m_file));
    func_th1.join();
    func_th2.join();
    return 0;
}

And don't forget that only one thread at a time should access the stream, so wrap access in a mutex of some sort.

Upvotes: 2

Related Questions