C++ 11有std :: condition_variable,它的等待函数是
template< class Predicate >
void wait( std::unique_lock<std::mutex>& lock, Predicate pred );
Run Code Online (Sandbox Code Playgroud)
它需要一个互斥量.
据我所知 - 它的notify_one可以在没有同步的情况下调用(我知道惯用的方法是将它与互斥锁一起使用).
我有一个对象,其已经在内部同步 -所以我并不需要一个互斥量来保护它.一个线程应该等待与该对象关联的某个事件,并且其他线程将被通知.
如何在C++ 11中没有互斥的情况下进行此类通知?即使用condition_variable很容易,但它需要一个互斥量.我想过使用假的互斥锁类型,但是在等待界面中固定了std :: mutex.
一个选项是轮询std :: atomic_flag + sleep,但我不喜欢睡觉.
我需要同步std::condition_variable/condition_variable_any::notify_one
吗?
据我所知,如果通知丢失是可以接受的 - 可以调用notify_one
不受保护(例如通过互斥).
例如,我看到了以下使用模式(抱歉,不记得在哪里):
{
{
lock_guard<mutex> l(m);
// do work
}
c.notify_one();
}
Run Code Online (Sandbox Code Playgroud)
但是,我检查了libstdc ++来源,我看到:
condition_variable :: notify_one
void condition_variable::notify_one() noexcept
{
int __e = __gthread_cond_signal(&_M_cond);
// XXX not in spec
// EINVAL
if (__e)
__throw_system_error(__e);
}
Run Code Online (Sandbox Code Playgroud)
和condition_variable_any :: notify_one:
void condition_variable_any::notify_one() noexcept
{
lock_guard<mutex> __lock(_M_mutex);
_M_cond.notify_one();
}
Run Code Online (Sandbox Code Playgroud)
这里是condition_variable_any的布局:
class condition_variable_any
{
condition_variable _M_cond;
mutex _M_mutex;
// data end
Run Code Online (Sandbox Code Playgroud)
即它只是condition_variable + mutex周围的薄包装.
所以,问题:
notify_one
的互斥体的任一condition_variable_any
或condition_variable
?在Eigen版本中,我使用"真正的"固定大小矩阵和向量,更好的算法(LDLT与uBlas的LU),它在内部使用SIMD指令.那么,为什么它在下面的例子中比uBlas慢?
我确信,我做错了 - Eigen 必须更快,或至少可比.
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/lu.hpp>
#include <boost/numeric/ublas/symmetric.hpp>
#include <boost/progress.hpp>
#include <Eigen/Dense>
#include <iostream>
using namespace boost;
using namespace std;
const int n=9;
const int total=100000;
void test_ublas()
{
using namespace boost::numeric::ublas;
cout << "Boost.ublas ";
double r=1.0;
{
boost::progress_timer t;
for(int j=0;j!=total;++j)
{
//symmetric_matrix< double,lower,row_major,bounded_array<double,(1+n)*n/2> > A(n,n);
matrix<double,row_major,bounded_array<double,n*n> > A(n,n);
permutation_matrix< unsigned char,bounded_array<unsigned char,n> > P(n);
bounded_vector<double,n> v;
for(int i=0;i!=n;++i)
for(int k=0;k!=n;++k)
A(i,k)=0.0;
for(int i=0;i!=n;++i)
{
A(i,i)=1.0+i;
v[i]=i;
}
lu_factorize(A,P);
lu_substitute(A,P,v);
r+=inner_prod(v,v);
} …
Run Code Online (Sandbox Code Playgroud) 我刚刚看过Herb Sutter的演讲:C++和2012年之后:Herb Sutter - 原子<>武器,2 of 2
他在std :: shared_ptr析构函数的实现中显示了错误:
if( control_block_ptr->refs.fetch_sub(1, memory_order_relaxed ) == 0 )
delete control_block_ptr; // B
Run Code Online (Sandbox Code Playgroud)
他说,由于memory_order_relaxed,删除可以放在fetch_sub之前.
在1:25:18 - 释放不保持在B线下面,它应该在哪里
怎么可能?在关系之前发生 - 之前/顺序 - 因为它们都在单线程中.我可能错了,但fetch_sub和delete之间也存在一个依赖关系.
如果他是对的,哪些ISO项目支持?
您推荐哪种算法快速求解固定维密集线性系统(N = 9)(矩阵是对称的,正半定的)?
类型是32位和64位浮点.
这样的系统将被解决数百万次,因此算法在维度方面应该相当快(n = 9).
可以理解用于所提出的算法的稳健 C++实现的PS示例.
1)"解决了数百万次"是什么意思?相同的系数矩阵与一百万个不同的右手术语,或一百万个不同的矩阵?
百万个不同的矩阵.
2)正_semi_definite意味着矩阵可以是奇异的(机器精度).你想怎么处理这个案子?只是提出错误,或尝试返回一些明智的答案?
提出错误是可以的.
Boost Lambda/Phoenix是否支持像lambda那样返回另一个lambda?
例如,这可以用来做某种currying:
std::cout << [](int x){return [=](int y){return x+y;};}(1)(2);
Run Code Online (Sandbox Code Playgroud)
如何实现与Boost Lambda/Phoenix类似的目的(+作为奖励 - 我们会得到多态行为)?
如何在Boost.Graph中合并两个顶点/合约边?
我需要将边缘从顶点A移动到顶点B,并删除顶点A - 是否有任何内置函数?或者也许adjacency_list有一些特别的东西?
如果没有这样的功能 - 为什么呢?我认为这是常见的图形操作.
编辑:我知道可以手动完成,但有一些极端情况(如保留边缘属性),这就是为什么它是在库中的好候选人.
我最感兴趣的是知道Boost.Graph是否已经有了这个操作(可能有一些奇特的名字?).如果不是 - 为什么这样的原始操作/算法不在图形库中.也许我错过了一些东西,而且这种操作不是原始的或很少使用.
我不需要半生不熟的快速概念验证
我使用git 1.7.4处理大型svn repo - 没关系.
我更新到git 1.7.8,现在,当我做"git svn dcommit"时,git做了一些多余的工作.在任务管理器中,我看到它做了大约1M的写操作(我正在使用SSD,所以它让我担心).它显示了.pdf和.doc文档的修改,例如它没有显示为1.7.4:
"c:/ Users /..../ AppData/Local/Temp/SOMEHASH_documentName.doc不是Word文档","错误:PDF文件已损坏 - 尝试重建外部参照表"
并且有许多这样的警告,可能大约200个.当git显示这样的警告时,我看到任务管理器中的写入计数增加了.
看起来git试图对二进制.pdf/.doc文件进行一些"智能"处理.但我不需要这个.我应该更改哪个配置选项来关闭这个多余的工作?
我正在阅读Anthony Williams的C++ Concurrency in Action.目前,我在他消耗memory_order_consume的地方.
在那个块之后有:
现在我已经介绍了内存排序的基础知识,现在是时候看一下更复杂的部分了
它让我有点害怕,因为我不完全理解几件事:
依赖顺序如何不同于同步?他们都创造了以前的关系.有什么区别?
我对以下示例感到困惑:
int global_data[]={ … };
std::atomic<int> index;
void f()
{
int i=index.load(std::memory_order_consume);
do_something_with(global_data[std::kill_dependency(i)]);
}
Run Code Online (Sandbox Code Playgroud)
kill_dependency到底做了什么?它杀死了哪种依赖?哪个实体之间?编译器如何利用这种知识?
是否可以使用memory_order_acquire安全地替换memory_order_consume的所有事件?即各方面都更严格吗?
在代码清单5.9中,我可以安全地替换
std::atomic<int> data[5]; // all accesses are relaxed
Run Code Online (Sandbox Code Playgroud)
同
int data[5]
Run Code Online (Sandbox Code Playgroud)
?即可以获取和释放用于同步访问非原子数据?
他描述了轻松,获得和释放的一些例子与男人在小隔间.是否有一些类似的简单描述seq_cst和消费?
我正在阅读Anthony Williams的C++ Concurrency in Action.在"理解轻松订购"部分,它有:
还有一些额外的东西可以告诉那个小隔间里的男人,比如"记下这个号码,并告诉我列表底部的内容 "(交换)和"如果底部的数字写下这个号码" 列表是那个; 否则告诉我我应该猜到的"(compare_exchange_strong),但这并不影响一般原则.
这是否意味着此类操作始终按修改顺序读取最后一个值(如果在约束之前没有其他内部线程发生)?即,有一些缓存更新/等(即使在轻松的订购)?