c++ - 为什么 ostringstream 在多线程环境下不能正常工作

标签 c++ linux multithreading stl pthreads

也许有些事情很奇怪。当我在我的多线程环境中使用 STL ostringstream 类时,我发现每个线程的执行时间随着线程数的增加而线性增加。我不知道为什么会这样。我尝试检查 ostringstream 源代码但找不到任何同步代码。 ostringsstream 中是否有一些同步位置?我用 snprintf 替换了 ostringsstream,性能大大提高。我的操作系统是 RHEL5.4 64BIT,我的服务器上有两个 xeon 5620 cpu。

下面是运行结果 我分别使用 1 个和 8 个线程,循环 1000000 个。左列是 threadid,右列是 运行时间。因此很明显,每个线程的运行时间随着线程数的增加而增加。

[host]$./multi_thread  1 1000000
1115760960:0.240113
[host]$./multi_thread  8 1000000
1105004864:8.17012
1115494720:8.22645
1125984576:8.22931
1136474432:8.41319
1094252864:8.73788
1167944000:8.74504
1157454144:8.74951
1146964288:8.75174

代码如下

#include <iostream>
#include <sstream>
using namespace std;

void * func(void * t)
{
        int n = *((int *) t);
        pthread_t pid = pthread_self();
        timeval t1, t2;
        gettimeofday(&t1, 0);
        for(int i = 0; i < n; i++)
        {
                ostringstream os;
                /*
                   char buf[255];
                   int ret = snprintf(buf, 30, "%d", 2000000);
                   buf[ret] = 0;
                 */
        }
        gettimeofday(&t2, 0);
#define DIFF(a, b) ((b.tv_sec - a.tv_sec) + (b.tv_usec - a.tv_usec) / 1000000.0)
        std::cout << pid << ":" << DIFF(t1, t2) << std::endl;
#undef DIFF

        return NULL;
}

int main(int argc, char *argv[])
{
        int m, n =0;
        m = atoi(argv[1]);
        n = atoi(argv[2]);
        pthread_t tid[m];
        for(int i = 0; i < m; i++)
                pthread_create(&tid[i], NULL, func, &n);
        for(int i = 0; i < m; i++)
                pthread_join(tid[i], NULL);
        return 0;
}

最佳答案

这似乎是一个已知问题。 Here是 MSVC 的解决方案:静态链接。也许这也适用于 Linux。

或者(建议用于 Sun Studio here),使流成为本地线程(而不是本地进程),以防止它们在其他线程访问它们时被每个线程锁定。

关于c++ - 为什么 ostringstream 在多线程环境下不能正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3707138/

相关文章:

c++ - 归并排序困惑的类型

c++ - C++ 中的私有(private)成员与临时变量

linux - 创建运行手册以执行 bash 脚本

c++ - 使用 C++ 线程/boost 线程的有效方法

c#为什么要把对象放在lock语句中

c++ - 在 wxWidgets (Windows) 的 ToolBar 中添加 ComboBox

c++ - 使用 operator new 进行内存分配并使用数据进行初始化

c - dup() 后跟来自多个线程或进程的 close()

linux - Git 检索在分支中修改的所有文件的列表

java - 如何每 15 秒运行一次计时器以及取消并重新启动计时器