2017-04-13 2 views
0

개체 중 하나를 C++11 표준을 사용하는 여러 스레드로 전달하려고합니다.출력 스트림 개체 및 다른 인수를 여러 스레드에 전달

모든 스레드가 다른 출력 파일에 쓰길 원하기 때문에 ofstream 개체를 전달하고 싶습니다.

나는 이런 식으로 스레드 및 출력 스트림을 초기화하고 있습니다 :

std::thread execution_threads[NUMBER_OF_THREADS]; // creating multiple empty threads 
std::ofstream output_files[NUMBER_OF_THREADS]; // Empty output streams 
// Opening and initializing the output files 

각 스레드는 두 개의 인수를 취하는 함수 실행 : 그래서

void execution(int thread_id, std::ofstream& output_file) 

을 나는 주위를 둘러 보았다 한 내가 ' 함수 func에 복수의 인수가있는 a,b,c,d이있는 경우 struct을 사용할 필요가없고 std::thread t(func, a,b,c,d);을 작성하여 전달할 수 있습니다. C++11 그래서 스레드를 실행하기 위해이 루프를 썼다 :

for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) { 
    execution_threads[i] = std::thread(execution, i, output_files[i]); 
} 

것은이 코드는이 오류와 함께 컴파일되지 않는다는 것입니다 :

Call to implicitly-deleted copy constructor of 
'typename decay<basic_ofstream<char, char_traits<char> > &>::type' 
(aka 'std::__1::basic_ofstream<char, std::__1::char_traits<char> >') 

나는이에 입력으로 struct를 사용하는 경우 동안 모든 것이 정상적으로 작동합니다.

이렇게하면 모든 것이 잘 작동하여 완벽하게 실행됩니다. 하지만 컴파일러가 다른 메소드를 사용하는 경우 삭제 된 복사본 생성자를 사용하려고한다는 사실을 알리는 이유를 알 수 없습니다.

도움 주셔서 감사합니다.

답변

2

std::thread은 인수의 사본을 저장합니다. std::ofstream과 같이 복사 할 수없는 객체를 전달하면 불만을 제기합니다.

당신은 두 가지 옵션이 있습니다

1) std::ofstream 객체의 배열을 보관하지 마십시오을; 스레드가 자신의 스트림을 저장하게하십시오. 이 경우, 스트림을 복사 할 필요 (미세 단지 이동)이 없다 : 당신은 그냥 스레드가 자신의 스트림을 구성 할 수이 경우 물론

for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) { 
    execution_threads[i] = std::thread(execution, i, std::ofstream{}); 
                //^^^^^^^^^^^^^^^ anonymous temporary 
} 

은 (어쩌면 바로 전달 파일 이름).

2) std::reference_wrapper<std::ofstream>을 스레드에 전달하십시오. std::reference_wrapper<T>T에 대한 참조를 보유하고 T&으로의 암시 적 변환을 갖는 개체이므로 스트림 자체 대신 참조를 복사하게됩니다. 당신은 T을 추론하고 입력을 줄이기 위해 std::ref 공장을 사용할 수 있습니다 (모든 std::reference_wrapper은 결국, 그건)

for (int i = 0; i < utils::NUMBER_OF_THREADS; i++) { 
    execution_threads[i] = std::thread(execution, i, std::ref(output_files[i])); 
                //^^^^^^^^ std::ref added 
} 

이있을 것 std::ofstream&를 포함하는 구조체를 통과하는 동일한 소유권과 수명 문제 모두 당신을 잎이 . 모든 스레드가 완료 될 때까지 output_files 배열이 살아남는 지 확인하는 것은 당신에게 달려 있습니다.