多平臺方法非常簡單。在標準規定他們應該使用哨兵時避免使用功能或操作員。 sentry是iostream類中的內部類,它確保每個輸出字符的流一致性,並且在多線程環境中,它鎖定輸出的每個字符的流相關互斥鎖。這避免了在低級別的比賽條件,但仍使輸出不可讀,因爲從兩個線程的字符串可能是同時輸出如下面的例子指出:
線程1應該寫:ABC
線程2應該寫的:def
輸出可能如下所示:adebcf而不是abcdef或defabc。這是因爲實施了哨兵來鎖定和解鎖每個角色。
該標準定義了它的所有功能和處理的IStream或ostream的運算符。避免這種情況的唯一方法是使用流緩衝區和您自己的鎖定(例如,每個字符串)。
我寫一個應用程序,其中的一些數據輸出到文件中並mesures速度。如果你在這裏添加一個函數,直接使用fstream輸出,而不使用緩衝區並刷新,你將看到速度差異。它使用提升,但我希望它不是你的問題。嘗試刪除所有的流緩衝區,看看有沒有它們的區別。我的情況是性能缺陷是2-3倍左右。
的following article由N.邁爾斯將解釋如何語言環境和哨兵在C++輸入輸出流工作。當然,你應該查看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 2009-07-29 13:50:06
不只是我的供應商;例如,POSIX需要它。 – 2009-07-29 13:56:22