я реализовал немного многопоточных приложений, которая делает следующее:Неблокирующая нитей остановка - или почему станд :: atomic_flag замедлиться мой код
MainThread
Основной поток запускает таймер используя
setitimer
и запускает до 8 потоков. Таймер из основного потока используется для повторного чтения из> файла (каждые 0,25 с). Когда таймер вызывается 20 раз (после ~ 5 секунд), я хочу, чтобы остановить потоки и получить количество выполненных вычислений каждой нитью.
MainThread.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
Выполните некоторые дорогие вычисления Whithin петли бесконечности. После определенного количества вычислений поток должен хранить количество выполненных вычислений . Это значение (количество вычислений) должно быть довольно точным, поэтому я думаю, что мне нужно остановить потоки (довольно) немедленно.
ThreadClass.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;
};
ComputationThread.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
).
Зачем вам нужно назначать поток конкретному ядру? – Slava
Потому что есть разные ядра – Hymir
OS делает это само по себе, вы только делаете что-то хуже – Slava