最强担保的解决方案是锁定所有此类操作整个向量(这意味着从无处不在的代码控制每操作,这实际上意味着创建一个同步向量)。
这可能是这么简单的东西会为你的目的做:
这个
int append(std::vector<int>& numbers, int number){
int retval = numbers.size();
// what if some other thread calls push_back(number) in between these calls?
numbers.push_back(number);
int newSize = numbers.size();
//this bit is as a short-cut in common, easy, cases
if(newSize = retval + 1) //no need for further complication
return retval;
while(++retval < newSize)
if(numbers[retval] == number)
return retval;
//If we get this far, numbers have been deleted, not added. More discussion below.
}
一件事是,如果线程推3,3,3,3,然后返回将是错误的指数,尽管它仍然是3的索引。是否可以取决于你的目的。
另一种情况是,如果矢量在此期间被弹出或以其他方式缩短,那么最好我们到达刚刚在上面的代码中发表评论的地步,更糟糕的是它的错误(因为它们在我们获得后再次弹出newSize,然后访问[retval]变得无效)。你需要考虑这种情况是否会发生(也许你从其他代码中知道它永远不会发生)以及如果发生这种情况该怎么办。
如果这个限制对你的用例来说太大了,那么生成一个完全同步的矢量是我能想到的最好的恐惧。
实际上,如果push_back()返回一个索引并不容易,因为push_back()本身不是线程安全的 – 2010-08-10 09:20:31
您需要保护容器免受所有并发写入的影响。并发普通push_back()已经需要向量外部同步 – 2010-08-10 09:20:57
请记住,对于许多真实世界的应用程序来说,制作小型线程安全操作并不是正确的解决方案:您应该考虑保护更大的代码块。如果您将它们用作通信机制,则线程安全集合是很好的。也就是说,这可能是这种情况。 – 2010-08-10 10:57:43