首先:我完全是互斥锁/多线程编程的新手,很抱歉提前出现任何错误......
我有一个运行多个线程的程序。线程(通常每个 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 获得锁,因为它有特权
那么,做这件事最好的(可能是最简单的)方法是什么?
我在想的是有一个名为“privileged_needs_lock”的布尔变量。
但我认为我需要另一个互斥锁来管理对这个变量的访问......我不知道这是否是正确的方法......
附加信息:
- 我的线程使用 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;
}
按照建议尝试了以下解决方案,但它不起作用(使用“ 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;
}