设为首页 加入收藏

TOP

string与线程安全
2011-12-24 22:24:12 】 浏览:2850
Tags:string 线程 安全
问题由来: 一个多线程程序运行一段时间后变得不正常,许多string类型变量的内容不正常。
因为程序在本机运行一直正常,而拿到一台服务器上运行有问题,怀疑服务器上是多CPU具有
真正的并发性造成某个未同步的变量操作异常。检查所有应该同步的代码,似乎都进行了正确的同步。
大致代码如下:

#include "stdafx.h"
#include 
<process.h>
#include 
<iostream>
#include 
<conio.h>
#include 
<string>

string                g_str;
CRITICAL_SECTION    g_cs;

void LockString() { EnterCriticalSection(&g_cs); };
void UnlockString() { LeaveCriticalSection(&g_cs); };

void SetString(char * szText)
{
    LockString();

    g_str 
= szText;

    UnlockString();
}


string GetString()
{
    
string strResult;

    LockString();

    strResult 
= g_str;

    UnlockString();

    
return strResult;
}


UINT ThreadProc(LPVOID lpParam)
{
    
// 为了使现象明显,这里进行了大量循环
    for(int i = 0; i < 200000; i++)
    
{
        
string strTmp = GetString();
    }


    
return 0;
}


#define        MAX_THREADS        200

int main(void)
{
    ::InitializeCriticalSection(
&g_cs);

    SetString(
"VC知识库");

    HANDLE hThreads[MAX_THREADS];

    UINT nThreadID;
    
int i;

    
// 开启线程
    for(i = 0; i < MAX_THREADS; i++)
        hThreads[i] 
= (HANDLE)_beginthreadex(NULL, 0, (unsigned (__stdcall *)(void *))ThreadProc, NULL, 0&nThreadID);

    
// 等待线程结束
    for(i = 0; i < MAX_THREADS; i++)
        ::WaitForSingleObject(hThreads[i], INFINITE);
    
    
// 输出结果
    cout << "string:" << GetString() << endl;

    ::DeleteCriticalSection(
&g_cs);

    getch();
    
return 0;
}


代码中唯一共用的变量g_str已经用临界区进行了同步,似乎没有问题了。但运行的时候却发现有时没有运行到cout时程序便异常退出,
或cout并没有输出正确的字符串。

经过调试最后发现问题是出在 string strTmp = GetString();
因为VC6自带的STL中的string采用cow方式,这种字符串的浅拷贝带来了多线程时的安全问题。而且这种错误隐藏得比较深,很难调试排错。

结论:

      如果要在多线程程序中进行string变量的传递,建议使用深拷贝的string类。

 

    标准库里面的string在多线程下并不保证是都是安全的,只提供两种安全机制:

    1.多个线程同时读取数据是安全的。

    ​2.只有一个线程在写数据是安全的。

 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇c++中,引用和指针的区别 下一篇线程安全与STRING类

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目