首先:我完全是互斥/多线程编程的新手,所以
提前对任何错误表示歉意...
我有一个运行多个线程的程序。线程(通常每
cpu核心)做了很多
计算和“思考”,然后有时他们决定打电话给
更新一些统计数据的特定(共享)方法。
统计更新的并发性是通过使用互斥体来管理的:
stats_mutex.lock();
common_area->update_thread_stats( ... );
stats_mutex.unlock();
现在来说说问题。
在所有这些线程中,有一个特定的线程几乎需要
实时优先级,因为它是唯一实际运行的线程。
对于“几乎实时优先级”我的意思是:
假设线程 t0 是“特权线程”,t1....t15 是普通线程
现在发生的是:
- 线程 t1 获取锁。
- 线程t2、t3、t0调用lock()方法并等待成功。
- 线程 t1 调用unlock()
- 线程 t2、t3、t0 中的一个(随机,据我所知)成功获取
锁,其他的继续等待。
我需要的是:
- 线程 t1 获取锁。
- 线程t2、t3、t0调用lock()方法并等待成功。
- 线程 t1 调用unlock()
- 线程 t0 获取锁,因为它具有特权
那么,做这件事最好的(可能是最简单的)方法是什么?
我的想法是有一个名为的 bool 变量
“特权需要锁”。
但我认为我需要另一个互斥体来管理对该变量的访问...我不
知道这是否是正确的方法...
附加信息:
- 我的线程使用 C++11(从 gcc 4.6.3 开始)
- 代码需要在 Linux 和 Windows 上运行(但目前仅在 Linux 上进行测试)。
- 锁定机制的性能不是问题(我的性能问题在于内部线程计算,线程数总是很低,每个CPU核心最多一两个)
任何想法表示赞赏。
谢谢
以下解决方案有效(三种互斥方式):
#include <thread>
#include <iostream>
#include <mutex>
#include "unistd.h"
std::mutex M;
std::mutex N;
std::mutex L;
void lowpriolock(){
L.lock();
N.lock();
M.lock();
N.unlock();
}
void lowpriounlock(){
M.unlock();
L.unlock();
}
void highpriolock(){
N.lock();
M.lock();
N.unlock();
}
void highpriounlock(){
M.unlock();
}
void hpt(const char* s){
using namespace std;
//cout << "hpt trying to get lock here" << endl;
highpriolock();
cout << s << endl;
sleep(2);
highpriounlock();
}
void lpt(const char* s){
using namespace std;
//cout << "lpt trying to get lock here" << endl;
lowpriolock();
cout << s << endl;
sleep(2);
lowpriounlock();
}
int main(){
std::thread t0(lpt,"low prio t0 working here");
std::thread t1(lpt,"low prio t1 working here");
std::thread t2(hpt,"high prio t2 working here");
std::thread t3(lpt,"low prio t3 working here");
std::thread t4(lpt,"low prio t4 working here");
std::thread t5(lpt,"low prio t5 working here");
std::thread t6(lpt,"low prio t6 working here");
std::thread t7(lpt,"low prio t7 working here");
//std::cout << "All threads created" << std::endl;
t0.join();
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
return 0;
}
按照建议尝试了以下解决方案,但它does not工作(使用“ g++ -std=c++0x -o test test.cpp -lpthread”编译):
#include <thread>
#include <mutex>
#include "time.h"
#include "pthread.h"
std::mutex l;
void waiter(){
l.lock();
printf("Here i am, waiter starts\n");
sleep(2);
printf("Here i am, waiter ends\n");
l.unlock();
}
void privileged(int id){
usleep(200000);
l.lock();
usleep(200000);
printf("Here i am, privileged (%d)\n",id);
l.unlock();
}
void normal(int id){
usleep(200000);
l.lock();
usleep(200000);
printf("Here i am, normal (%d)\n",id);
l.unlock();
}
int main(){
std::thread tw(waiter);
std::thread t1(normal,1);
std::thread t0(privileged,0);
std::thread t2(normal,2);
sched_param sch;
int policy;
pthread_getschedparam(t0.native_handle(), &policy, &sch);
sch.sched_priority = -19;
pthread_setschedparam(t0.native_handle(), SCHED_FIFO, &sch);
pthread_getschedparam(t1.native_handle(), &policy, &sch);
sch.sched_priority = 18;
pthread_setschedparam(t1.native_handle(), SCHED_FIFO, &sch);
pthread_getschedparam(t2.native_handle(), &policy, &sch);
sch.sched_priority = 18;
pthread_setschedparam(t2.native_handle(), SCHED_FIFO, &sch);
tw.join();
t1.join();
t0.join();
t2.join();
return 0;
}