2013-06-01 163 views
1

所以我有多个线程访问此函数来检索数据库信息,它是线程安全的吗?C++向量是线程安全的吗?多线程

vector<vector<string> > Database::query(const char* query) 
{ 
    pthread_rwlock_wrlock(&mylock); //Write-lock 
    ... 
    vector<vector<string> > results; 
    results.push... 
    pthread_rwlock_unlock(&mylock); //Write-lock 

    return results; 
} 

对于编辑 - >有时'修复'>>到>>不是一个好主意,但感谢其余的。

+0

很难确定你在问什么。使用像这样的本地向量是线程安全的,因为它是在堆栈上创建的。但是我们不能告诉你,如果你的函数是线程安全的。 我可以告诉你,这将是低效的,因为在构建你的向量的字符串向量之后,你会返回它的一个副本而不是原始的。 – kfsone

回答

1

一般来说,多个线程可以容纳“读”锁。只有一个线程可以保持“写入”锁定。当有“写入”锁定时,可能不会持有“读取”锁定。

这意味着,虽然mylock被锁定在query方法内,但没有其他人可以将其锁定为读取或写入,因此它是线程安全的。你可以阅读更多关于读者 - 作家锁定here。无论你是否需要锁定在那里的互斥锁是另一个问题。然而,代码不是exception-safe。您必须雇用RAII才能自动解锁互斥锁,包括堆栈解除锁定。

+0

关于异常安全的任何教程?或者只是一个简单的try {} catch()会做什么? –

+0

@БайИван:看看[这个问题](http://stackoverflow.com/questions/2635882/raii-tutorial-for-c)。 Try-catch也可以,但通常更容易出错并且难写。 – 2013-06-01 23:12:04

2

由于results是一个局部变量,因为每个线程都会有唯一的副本(它位于堆栈上,以某种方式动态分配的向量的内容等),所以它本身是安全的, 。所以只要你的数据库是线程安全的,你根本不需要任何锁。如果数据库不是线程安全的,当然你需要保护它。

正如在其他答案中指出的那样,如果由于某种原因,例如创建一个字符串导致throw bad_alloc;,您需要处理该问题的后果,并确保该锁已解锁(除非您真的希望以使所有其他线程死锁!)

+0

这是我需要听到的;数据库不是线程安全的,因此我锁定它:) –

0

它是线程安全的,因为results被创建为局部变量,因此只有一个线程会访问此方法中的任何结果实例。

如果您因为某些其他原因需要线程安全的向量,请在Threadsafe Vector Class for C++上查看此答案。