четверг, 11 марта 2010 г.

Multithreaded std::cout.

Постоянно встречался с тем, что конструкция типа:
std::cout << "123" << a << "456" << b << std::endl;
работает не очень хорошо из нескольких тредов(потоков) одновременно.
Каждый такой оператор "<<" представляет из себя отдельный вызов функции и может вполне случиться, что выводимые данные из разных потоков перемешаются.

Придумал небольшой трюк для устранения этой проблемы.
Теперь вместо #include <iostream> подключаю свой #include "mt_iostream".

Содержимое mt_iostream:
#include <iostream>
#include <sstream>

namespace std
{
class mt_ostream : public ostringstream
{
public:
mt_ostream() : ostringstream() {}
~mt_ostream()
{
cout << str();
}
};
} // namespace std

#define cout (static_cast<mt_ostream&>mt_ostream())

Подсветка синтаксиса выполнена при помощи Notepad++




И в качестве бонуса, небольшой trick для получения различных последовательностей rand() в разных тредах (обычно они совпадают). В начале работы каждого из тредов вызывайте функцию srand, передавая ей параметром текущее время. Это вы знали и без меня, это не помогает. Вот этот макрос поправит ситуацию:
#define srand(x) srand(x + GetCurrentThreadId())

Читать дальше

вторник, 2 марта 2010 г.