[英]c++ member function thread safe
我正在编写一个用于记录消息的函数。 我将从不同的线程调用此打印功能。 我的代码如下:
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是否有可能被弄错,从而打印错误的值。? 我希望我的问题清楚。
您的函数将按预期工作,因为myline
是一个局部变量(每个线程都有自己的堆栈,所以会有自己的myline
实例)
如果要从不同的线程调用此函数,并且对参数const char* s
进行的任何更改都受互斥锁m_Mutex
保护,那么一切都会好起来的。
编辑
实际上,从不同的线程调用此函数时,每次调用都将具有其自己的堆栈,并且看到它为const char*
您无法更改参数,因此无需使用互斥量对其进行保护。
您的变量s
是被调用线程本地的变量,它是const
。
然后复制到局部变量myline
中绝对不会造成任何混乱,因为每个线程都有它的调用堆栈,当调用此函数时,该线程上会存在myline
的实例,该实例是完全独立的并且独立于任何其他线程。
这取决于您如何调用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
函数同步访问字符串的不确定性,并将职责完全移到调用printLog
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.