我正在编写一个用于记录消息的函数。我将从不同的线程调用这个打印函数。我的代码如下:
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 Thread2”,...是否有可能将常量字符*弄乱打印错误值??我希望我的问题是清楚的。
发布于 2012-05-13 00:16:54
您的函数将按照您的预期工作,因为myline是一个局部变量(每个线程都有自己的堆栈,因此会有自己的myline实例)
发布于 2012-05-13 00:16:46
如果你从不同的线程调用这个函数,并且你对参数const char* s所做的任何更改都受到互斥锁m_Mutex的保护,那么你就会很好,没有什么会变得混乱。
编辑
实际上,当从不同的线程调用这个函数时,每个调用都有它自己的堆栈,并且看到它互斥( const char* ),你不能改变你的参数,所以不需要用互斥锁来保护它。
您的变量s是调用它的线程的本地变量,它是const。
然后复制到本地变量myline肯定不会造成任何麻烦,因为每个线程都有自己的调用堆栈,当这个函数被调用时,调用堆栈上有一个myline的实例,它是完全独立于任何其他线程的。
发布于 2012-05-13 01:52:01
这取决于您调用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指针的引用也必须发生在临界区中。
你的设置的根本问题是,原始字符指针没有隐含的语义来告诉用户哪些行为是可以接受的,哪些是不可以接受的。如果你通过值传递了一个实际的std::string,你就可以从printLog函数中消除同步访问字符串的不确定性,并将责任完全转移到调用者身上。
https://stackoverflow.com/questions/10565348
复制相似问题