1

我正在编写一个记录消息的函数。我将从不同的线程调用这个打印函数。我的代码如下:

MyLog::printLog(const char* s)
    {

            std::string myline(s);
            //m_Mutex is class member and there will be only object for this class
            // shared by all threads
            int ret = pthread_mutex_lock(&m_Mutex);
            if ( ret != 0 )
            {
                    std::cout<<" trying to lock same mutex char* "<<std::endl;

            }


            //code to log message in File

            pthread_mutex_unlock(&m_Mutex);
     }

我的问题是,如果上面的函数是从不同的线程调用的,参数是 "from thread1" , "from thread 2" ,......是否有可能 const char *s 会混淆打印错误的值。?我希望我的问题很清楚。

4

3 回答 3

3

您的函数将按您的预期工作,因为myline它是一个局部变量(每个线程都有自己的堆栈,因此会有自己的实例myline

于 2012-05-12T16:16:53.750 回答
1

如果您从不同的线程调用此函数,并且您对参数所做的任何更改const char* s都受到互斥锁的保护,m_Mutex那么您会很好,不会有任何混乱。

编辑

实际上,当从不同的线程调用时,对这个函数的每次调用都会有它自己的堆栈,并且看到它const char*你不能改变你的参数,所以没有必要用互斥锁来保护它。

s的变量是调用它的线程的本地变量,它是const.

然后复制到局部变量myline绝对不会弄乱任何东西,因为每个线程都有它的调用堆栈,其中存在一个调用myline此函数时的实例,它完全独立于任何其他线程。

于 2012-05-12T16:16:45.807 回答
1

这取决于您如何调用该printLog函数。如果您传递给函数的地址的字符串被不同的线程改变,那么您可能无法在 log 函数中看到一致的视图。如果你传入一个指向不可变字符串的指针,例如文字,那么你就可以了。

这是一个很好的例子:

void from_thread_one()
{
    MyLog::printLog("Hello World");  // immutable string
}

void from_thread_two()
{
    MyLog::printLog("Another text");  // ditto
}

另一方面,这是一个不正常且有比赛的示例:

char globalString[] = "This is a really long string";

void from_thread_one()
{
    globalString[5] = 'A';
    MyLog::printLog(globalString);
}

void from_thread_two()
{
    globalString[8] = 'Q';
    MyLog::printLog(globalString);
}

在此设置中,您正在制作字符串的副本(通过std::string myline(s);),而指向的数组的内容s可以同时在另一个线程中更改。在这种情况下,取消对 char 指针的引用也必须发生在临界区内。

您的设置的基本问题是原始 char 指针没有隐含的语义来告诉用户哪些行为是可接受的,哪些是不可接受的。如果您通过实际std::string值传递,您将消除从函数同步访问字符串的不确定性,printLog并将责任完全转移到调用者身上。

于 2012-05-12T17:52:01.467 回答