template <typename R>
class shared_future
{
...
// move support
shared_future(shared_future && other);
shared_future(unique_future<R> && other);
shared_future& operator=(shared_future && other);
shared_future& operator=(unique_future<R> && other);
...
}
Run Code Online (Sandbox Code Playgroud)
究竟是那些双括号?我浏览了"BS C++ Langauge 3d版"并找不到任何解释.
我正在尝试理解一些导致PC-Lint悲伤的提升代码,并以一种我认为不合法的C++但在VS2008中编译好的方式使用friend关键字.
我以为我理解朋友是宣告课程和功能的一种方式.我认为在这样的函数定义上使用是不合法的.但是,MSDN页面非常具体:
可以在类声明中定义友元函数.这些函数是内联函数,就像成员内联函数一样,它们的行为就好像它们是在看到所有类成员之后但在类作用域关闭之前(类声明结束)之前立即定义的.
在类声明中定义的友元函数不在封闭类的范围内考虑; 他们在文件范围内.
所以我理解这是合法的,如果不寻常的语法.
我不确定它是什么,因为宣布朋友的正常原因是为了增加访问权限.但是,结构的成员默认都是公共的,因此这里没有这样的好处.
我错过了一些深刻的东西,或者这只是一些风格上的提升问题,有人不喜欢在结构体之后放入内联自由函数?
请注意,_InterlockedIncrement是Win32上的内部函数.
# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement
struct thread_data_base
{
long count;
detail::win32::handle_manager thread_handle;
detail::win32::handle_manager interruption_handle;
boost::detail::thread_exit_callback_node* thread_exit_callbacks;
boost::detail::tss_data_node* tss_data;
bool interruption_enabled;
unsigned id;
thread_data_base():
count(0),thread_handle(detail::win32::invalid_handle_value),
interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
thread_exit_callbacks(0),tss_data(0),
interruption_enabled(true),
id(0)
{}
virtual ~thread_data_base()
{}
friend void intrusive_ptr_add_ref(thread_data_base * p)
{
BOOST_INTERLOCKED_INCREMENT(&p->count);
}
...
};
Run Code Online (Sandbox Code Playgroud)
更新
感谢Chubsdad在下面的回答,我想我现在明白了,我对正在发生的事情的总结:
intrusive_ptr_add_ref(somePtrToThreadData)我试图在一个单独的线程上运行模板函数,但IntelliSense(VC++ 2010 Express)一直给我错误:"错误:没有构造函数的实例"boost :: thread :: thread"匹配参数列表"如果我尝试编译我得到这个错误:"错误C2661:'boost :: thread :: thread':没有重载函数需要5个参数"
错误只发生在我添加模板后所以我确定它与它们有关但我不知道是什么.
我传递给boost :: thread的两个参数是定义为的模板函数:
template<class F>
void perform_test(int* current, int num_tests, F func, std::vector<std::pair<int, int>>* results);
Run Code Online (Sandbox Code Playgroud)
和:
namespace Sort
{
template<class RandomAccessIterator>
void quick(RandomAccessIterator begin, RandomAccessIterator end);
} //namespace Sort
Run Code Online (Sandbox Code Playgroud)
我试着像这样调用boost :: thread:
std::vector<std::pair<int, int>> quick_results;
int current = 0, num_tests = 30;
boost::thread test_thread(perform_test, ¤t, num_tests, Sort::quick, &quick_results);
Run Code Online (Sandbox Code Playgroud) 编译器:linux上的clang ++ x86-64.
已经有一段时间了,因为我编写了任何复杂的低级系统代码,并且我对系统原语(windows和pthreads/posix)进行了编程.所以,#s和out的内容已经从我的记忆中消失了.我正在boost::asio和boost::thread目前一起工作.
为了模拟针对异步函数执行器的同步RPC(在请求被编辑的地方boost::io_service有多个线程),我正在使用boost同步原语.为了好奇,我决定使用这些原语.这就是我所看到的.io::service::runio_serviced::postsizeof
struct notification_object
{
bool ready;
boost::mutex m;
boost::condition_variable v;
};
...
std::cout << sizeof(bool) << std::endl;
std::cout << sizeof(boost::mutex) << std::endl;
std::cout << sizeof(boost::condition_variable) << std::endl;
std::cout << sizeof(notification_object) << std::endl;
...
Run Code Online (Sandbox Code Playgroud)
输出:
1
40
88
136
Run Code Online (Sandbox Code Playgroud)
互斥锁的四十个字节?? ?? ?WTF!88为条件_变量!!! 请记住,我被这个体积臃肿击退,因为我想,可能造成上百的应用程序notification_object的
这种便携性开销似乎很荒谬,有人可以证明这一点吗?据我所知,这些原语应该是4或8字节宽,具体取决于CPU的内存模型.
c++ boost-thread micro-optimization boost-asio systems-programming
在使用Boost线程的单个生产者/单个消费者应用程序中,如果生产者线程cond_var.notify_one()在消费者线程调用之前进行多次调用,会发生cond_var.wait(lock)什么?
是否会notify_one堆叠额外的呼叫,以便每次呼叫.wait()将与呼叫1:1对应.notify_one()?
编辑实现并发队列的一个常见引用示例有以下方法:
void push(Data const& data)
{
boost::mutex::scoped_lock lock(the_mutex);
the_queue.push(data);
lock.unlock();
the_condition_variable.notify_one();
}
void wait_and_pop(Data& popped_value)
{
boost::mutex::scoped_lock lock(the_mutex);
while(the_queue.empty())
{
the_condition_variable.wait(lock);
}
popped_value=the_queue.front();
the_queue.pop();
}
Run Code Online (Sandbox Code Playgroud)
我使用了一些非常相似的代码,并且经历了一些奇怪的内存增长,这似乎可以解释为消费者线程没有为每个人唤醒.notify_one()(因为它仍在忙于其他工作),并且想知道是否缺少"堆叠"可能是原因.
如果(有时)消费者线程无法跟上生产者线程,似乎没有堆叠这个代码就会失败.如果我的理论是正确的,我会很感激有关如何修复此代码的建议.
我遇到了boost::sleep()功能上的奇怪问题.我有这个基本代码:
#include <sys/time.h>
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
void thread_func()
{
timeval start, end;
gettimeofday( &start, NULL );
boost::this_thread::sleep( boost::posix_time::milliseconds(1) ); // usleep(1000) here works just fine.
gettimeofday( &end, NULL );
int secs = end.tv_sec - start.tv_sec;
int usec = end.tv_usec - start.tv_usec;
std::cout << "Elapsed time: " << secs << " s and " << usec << " us" << std::endl;
}
int main()
{
thread_func();
boost::thread thread = boost::thread( thread_func );
thread.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
问题是boost::sleep() …
我的应用程序有一个类似于以下代码的部分
void SomeClass::OtherMethod(std::vector<std::string>& g)
{
g.pushback("Something");
}
void SomeClass::SomeMethod()
{
std::vector<std::string> v;
boost::thread t(boost::bind(&SomeClass::OtherMethod,this,v)
t.join();
std::cout << v[0]; //Why is this empty when the vector created on stack
}
Run Code Online (Sandbox Code Playgroud)
我想知道为什么当在堆栈上创建向量时向量v为空,并且当它在堆上创建时它可以工作.我期待上面的代码能够工作,因为即使在堆栈上创建了向量,向量仍然在范围内.
我想等待一段时间的条件.我读了升压文件和它似乎是最好使用功能wait_for与谓词,如所描述这里.
不幸的是,这个例子对我来说并不是很有用.我该如何编写谓词?我试着编写上面报告的代码但是visual studio编译器抱怨:c:\boost\boost\thread\win32\condition_variable.hpp(394): error C2064: term does not evaluate to a function taking 0 arguments
这是代码的一部分:
class MyClass{
boost::mutex mutex;
boost::condition_variable myCondition;
//...
void foo();
bool myPredicate();
}
void MyClass::foo(){
boost::unique_lock<boost::mutex> lock(mutex);
boost::chrono::microseconds period(25000);
// ...
boost::chrono::system_clock::time_point wakeUpTime = boost::chrono::system_clock::now() + period;
if(myCondition.wait_until(lock,wakeUpTime,MyClass::myPredicate) == true){/...}
}
bool MyClass::myPredicate(){
if(...)
return true;
else
return true;
}
Run Code Online (Sandbox Code Playgroud)
使用wait_for谓词的正确方法是什么?
从这个示例项目的输出中,我看到我的对象的三个副本在我只期望一个时创建.并且只想要一个.我该怎么解决这个问题?
在我的真实代码中,ThreadedThing是一个更大/更重的类,它位于一个线程池中,我宁愿只有我真正需要的那么多.但我写了一个小演示应用程序(下面)来演示这种行为.我从增强线程样本中复制了基本代码,所以我希望它能正常工作,所以我担心这是一个C++新手的问题.
我之前编写过多线程代码,但是在Delphi而不是C++中.对于这个代码,valgrind说没有泄漏,这一切都很好,但仍然有三个对象被创建,我宁愿有一个.
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
class ThreadedThing {
public:
ThreadedThing() {
cout << "ThreadedThing created" << endl;
}
ThreadedThing(const ThreadedThing &orig) {
cout << "ThreadedThing copy created" << endl;
}
~ThreadedThing() {
cout << "ThreadedThing destroyed" << endl;
}
void operator()() {
cout << "ThreadedThing running" << endl;
sleep(2);
}
};
int main() {
std::vector < shared_ptr < boost::thread >> threads;
cout << "Started" << endl;
ThreadedThing thing;
std::shared_ptr<boost::thread> thread(new boost::thread(thing));
threads.push_back(thread);
for (std::vector < …Run Code Online (Sandbox Code Playgroud) 我使用Google基准测试进行了以下3个测试,结果使我感到惊讶,因为RW锁定比释放模式下的简单互斥锁慢约4倍。(在调试模式下,速度比简单互斥锁慢约10倍)
void raw_access() {
(void) (gp->a + gp->b);
}
void mutex_access() {
std::lock_guard<std::mutex> guard(g_mutex);
(void) (gp->a + gp->b);
}
void rw_mutex_access() {
boost::shared_lock<boost::shared_mutex> l(g_rw_mutex);
(void) (gp->a + gp->b);
}
Run Code Online (Sandbox Code Playgroud)
结果是:
2019-06-26 08:30:45
Running ./perf
Run on (4 X 2500 MHz CPU s)
CPU Caches:
L1 Data 32K (x2)
L1 Instruction 32K (x2)
L2 Unified 262K (x2)
L3 Unified 4194K (x1)
Load Average: 5.35, 3.22, 2.57
-----------------------------------------------------------
Benchmark Time CPU Iterations
-----------------------------------------------------------
BM_RawAccess 1.01 ns 1.01 ns 681922241
BM_MutexAccess 18.2 ns …Run Code Online (Sandbox Code Playgroud)