- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我实现了一个小的多线程应用程序,它执行以下操作:
主线程
A main thread starts a timer using
setitimer
and starts up to 8 threads. The timer from the main thread is used to read repeatedly from > a file (every 0.25s). When the timer is called 20 times (after ~5s), I want to stop the threads and get the amount of computations done by every thread.
主线程.h
class MainThread {
private:
int counter;
ThreadManager tm;
bool registerTimer(double seconds);
void startTimerWithInterval(double interval);
void read() {
/**
* If counter >= 20, call stopWorker on all threads
*/
tm.stopWorkers();
}
public:
MainThread():counter(0){}
}
WorkerThreads
Perform some expensive computations whithin an infinity loop. After a certain amount of computations, the thread has to store the number of computations it performed. This value (amount of computations) has to be quite accurate, so i think I have to stop the threads (quite) immediatly.
线程类.h
class WorkerThread {
private:
/**
* ...
*/
std::atomic_flag keep_Running = ATOMIC_FLAG_INIT;
static void* run(void* args) {
((WorkerThread*)args)->process();
pthread_exit(nullptr);
return nullptr;
}
public:
/**
* ...
*/
bool startWorker() {
keep_Running.test_and_set();
bool result = (pthread_create(&thread, pthread_attr, run, this) == 0);
if(!result) {
keep_Running.clear();
}
return result;
}
void stopWorker() {
keep_Running.clear();
}
bool keepRunning() {
return keep_Running.test_and_set();
}
virtual void process() = 0;
};
计算线程.h
class ComputationThread : public WorkerThread {
public:
virtual void process() override {
/**
* Perform computations with ~400MB data
* check every 16B, whether keepRunning still true
*/
bool keep_running = true;
while(keep_running) {
/**
* Process 4B
*/
keep_running = keepRunning();
}
}
};
如果我使用某种标志来跟踪线程的运行状态,我必须使该标志成为线程安全的,不是吗?我尝试了 std::atomic_flag
,因为它应该是无锁的并且具有原子操作,但这会导致性能急剧下降。我的问题是,std::atomic_flag
是否会导致性能下降,或者这仅仅是因为我过于频繁地执行检查?有谁知道更好的方法吗?
在你问之前,我必须使用 pthread
而不是 std::thread
将线程分配给线程创建中的指定核心(使用 pthread_attrib_t
)。
最佳答案
不要使用 std::atomic_flag
.
它意味着低级别 atomic
原始的,因此接口(interface)非常有限。
它的主要限制是您只能通过在单个 atomic
中将它设置为 true 来测试它的值。调用名为 test_and_set()
这是一个读取-修改-写入操作 (RMW),它在所有内核之间执行昂贵的同步。由于您在每次循环迭代中都调用它,因此它会显着减慢速度。
使用常规 atomic<bool>
完成后进行设置。这样,在循环内你只需要读取它,这是一个 atomic
加载并转换为常规 mov
手术。设置特定的内存顺序不会影响性能(至少在 X86 上)。
关于c++ - 非阻塞 pthread 停止 - 或者为什么 std::atomic_flag 会减慢我的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41882223/
我有一个 struct,我们称它为 struct foo,我想向其添加一个 atomic_flag 变量。到目前为止,我一直在 callocing 结构,因为它主要需要进行零初始化。我应该如何初始化
我正在使用 C++ std::atomic_flag作为一个原子 bool 标志。将标志设置为真或假不是问题,但是如何在不将其设置为某个值的情况下查询标志的当前状态?我知道有方法'atomic_fla
我在 cplusplus.com 尝试了使用 atomic_flag 的基本示例. Valgrind 的 Helgrind 工具报告 164 errors from 28 contexts (supp
以这种方式初始化 std::atomic_flag 真的很有必要: std::atomic_flag flag = ATOMIC_FLAG_INIT; 在我看来它应该有相同的结果: std::atom
我正在尝试熟悉 c++11 的新内存排序概念,并且相信我实际上已经很好地掌握了它们,直到我偶然发现了自旋锁的这个实现: #include namespace JayZ { namespace
我正在尝试熟悉 c++11 的新内存排序概念,并且相信我实际上已经很好地掌握了它们,直到我偶然发现了自旋锁的这个实现: #include namespace JayZ { namespace
使用 std::atomic_flag 时, 必须小心始终使用 ATOMIC_FLAG_INIT 显式初始化它,这是容易出错的。然而,有一个默认构造函数...那么,在让标志处于未指定状态的默认构造函数
在类构造函数中初始化 std::atomic_flag 的安全方法是什么? This question似乎在问我问的同一个问题 - 除了这里提问者提示编译器问题。 我的问题与 C++ 标准本身有关。根
摘自 C++ 并发实践: difference between std::atomic and std::atomic_flag is that std::atomic may not be lock
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 3 年前。 Improve this qu
比较 std::atomic_flag 到std::atomic_bool (又名 std::atomic ),在我看来 std::atomic_flag只是有一个更简单的界面。它仅提供测试+设置和清
我有一个简单的 bool 值,需要以线程安全的方式进行测试和设置。如果一个线程已经在工作,我希望第二个线程退出。如果我明白std::atomic_flag正确,这应该可以正常工作。但是,我不确定我是否
我正在尝试使用 atomic_flag 实现自旋锁。我知道使用 C++11 我必须初始化 atomic_flag 变量,但我无法编译它。我的代码如下所示: class SpinLock { publ
抱歉冗长 - 我已尽力将我的代码示例压缩为一个功能最少的类和 main() 方法。 我正在尝试使用 atomic_flag 通知我的工作线程中的 _rx() 在调用 stop() 时退出。 我认为问题
当调用notify_one()时,是否有关于在atomic_flag上调用wait()的线程被唤醒的顺序的公平性信息。它们是否按照进入 wait() 的确切顺序被唤醒,可以说是 FIFO 吗? 原子标
自 std::lock_guard不适用于 std::atomic_flag我已经实现了我自己的版本: class atomic_guard { public: inline atomic_g
使用 MS Visual C++2012 一个类有一个std::atomic_flag类型的成员 class A { public: ... std::atomic_flag
std::atomic_flag 有 2 个具有这些默认 std::memory_order 的函数: void clear(std::memory_order order = std::memory
我想知道使用 Windows 的 interlockedXXX 函数和使用 std::atomic_flag 访问 bool 值之间有什么区别。 据我所知,它们都是无锁的,您无法直接设置或读取 ato
我实现了一个小的多线程应用程序,它执行以下操作: 主线程 A main thread starts a timer using setitimer and starts up to 8 threads
我是一名优秀的程序员,十分优秀!