멀티 플랫폼 방식은 매우 간단합니다. 표준이 센트리를 사용해야한다고 명시한 기능이나 운영자는 피해야합니다. 보초는 모든 출력 문자에 대한 스트림 일관성을 보장하는 iostream 클래스의 내부 클래스이며 멀티 스레드 환경에서는 출력되는 각 문자에 대한 스트림 관련 뮤텍스를 잠급니다.
스레드 1 작성해야 : ABC
스레드 2 작성해야 : 데프
두 개의 스레드에서 문자열 출력은 다음 예와 같이 동시에 할 수 있기 때문에이 상태, 낮은 수준에서 경쟁 조건을 방지하지만 여전히 출력이 읽을 수 있습니다
출력은 abcdef 또는 defabc 대신 adebcf처럼 보일 수 있습니다. 센트리가 문자마다 잠금 및 잠금 해제되도록 구현 되었기 때문입니다.
표준은 istream 또는 ostream을 처리하는 모든 함수와 연산자에 대해이 표준을 정의합니다. 이를 방지하는 유일한 방법은 스트림 버퍼와 자체 잠금 (예 : 문자열 당)을 사용하는 것입니다.
나는 데이터를 파일로 출력하고 속도를 측정하는 app을 작성했다. 버퍼를 사용하지 않고 fstream을 직접 사용하여 플러시하는 함수를 여기에 추가하면 속도 차이가 나타납니다. 그것은 부스트를 사용하지만, 당신에게 문제가되지 않기를 바랍니다. 모든 streambuffers를 제거하고 차이가 있는지 여부를 확인하십시오. 저의 경우 성능 결점은 2-3 단계였습니다.
N. Myers의 following article은 C++ IOStreams에서 로케일과 보초가 어떻게 작동하는지 설명합니다. 그리고 ISO C++ 표준 문서를 살펴보아야합니다.이 함수는 센트리를 사용합니다.
행운을 빕니다,
Ovanes 고려해야 할
#include <vector>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <boost/progress.hpp>
#include <boost/shared_ptr.hpp>
double do_copy_via_streambuf()
{
const size_t len = 1024*2048;
const size_t factor = 5;
::std::vector<char> data(len, 1);
std::vector<char> buffer(len*factor, 0);
::std::ofstream
ofs("test.dat", ::std::ios_base::binary|::std::ios_base::out);
noskipws(ofs);
std::streambuf* rdbuf = ofs.rdbuf()->pubsetbuf(&buffer[0], buffer.size());
::std::ostreambuf_iterator<char> oi(rdbuf);
boost::progress_timer pt;
for(size_t i=1; i<=250; ++i)
{
::std::copy(data.begin(), data.end(), oi);
if(0==i%factor)
rdbuf->pubsync();
}
ofs.flush();
double rate = 500/pt.elapsed();
std::cout << rate << std::endl;
return rate;
}
void count_avarage(const char* op_name, double (*fct)())
{
double av_rate=0;
const size_t repeat = 1;
std::cout << "doing " << op_name << std::endl;
for(size_t i=0; i<repeat; ++i)
av_rate+=fct();
std::cout << "average rate for " << op_name << ": " << av_rate/repeat
<< "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
<< std::endl;
}
int main()
{
count_avarage("copy via streambuf iterator", do_copy_via_streambuf);
return 0;
}
C의 stdio.h 함수는 스레드 세이프가 아닙니다. 그것은 당신의 공급 업체이기도합니다. – MSalters
내 공급 업체 만이 아닙니다. 예를 들어, POSIX에서는이를 요구합니다. –