有条件地获得std :: mutex

时间:2017-03-29 02:34:28

标签: c++ opencv c++11 mutex

我有一个使用GPU的多线程应用程序,它本质上是单线程的,我使用的实际API cv::gpu::FAST_GPU,当我尝试使用它们多线程时会崩溃,所以基本上我有:

static std::mutex s_FAST_GPU_mutex;

{
    std::lock_guard<std::mutex> guard(s_FAST_GPU_mutex);
    cv::gpu::FAST_GPU(/*params*/)(/*parameters*/);
}

现在,对代码进行基准测试显示,FAST_GPU()处于隔离状态比CPU FAST()更快,但在实际应用程序中,我的其他线程会花费大量时间等待锁定,因此整体吞吐量更糟糕的是。

查看文档,at this answer似乎可能会这样:

static std::mutex s_FAST_GPU_mutex;
static std::unique_lock<std::mutex> s_FAST_GPU_lock(s_FAST_GPU_mutex, std::defer_lock);

{
    // Create an unlocked guard
    std::lock_guard<decltype(s_FAST_GPU_lock)> guard(s_FAST_GPU_lock, std::defer_lock);
    if (s_FAST_GPU_lock.try_lock())
    {
        cv::gpu::FAST_GPU(/*params*/)(/*parameters*/);
    }
    else
    {
        cv::FAST(/*parameters*/);
    }
}

但是,这不会编译,因为std::lock_guard只接受std::adopt_lock。我该如何正确实现?

2 个答案:

答案 0 :(得分:9)

同时从多个线程访问@IBOutlet weak var lbl: UILabel! var time = 0 var timer = Timer() @IBOutlet weak var start: UIButton! @IBOutlet weak var stop: UIButton! @IBOutlet weak var pause: UIButton! @IBAction func start(_ sender: AnyObject) { timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.action), userInfo: nil, repeats: true) } @IBAction func stop(_ sender: AnyObject) { //timer.invalidate() time = 0 lbl.text = "0" } @IBAction func pause(_ sender: AnyObject) { timer.invalidate() } override func viewDidLoad() { super.viewDidLoad() } func action() { time += 1 lbl.text = String(time) } 实际上是不安全的。我不熟悉你问题的opencv部分,所以这个答案主要关注互斥锁/锁的使用。

unique_lock

尝试获取锁定,如果成功,则使用static std::mutex s_FAST_GPU_mutex; { // Create a unique lock, attempting to acquire std::unique_lock<std::mutex> guard(s_FAST_GPU_mutex, std::try_to_lock); if (guard.owns_lock()) { cv::gpu::FAST_GPU(/*params*/)(/*parameters*/); guard.unlock(); // Or just let it go out of scope later } else { cv::FAST(/*parameters*/); } } ,然后释放锁定。如果已经获取了锁,则调用第二个分支,调用FAST_GPU

答案 1 :(得分:5)

如果采用处于锁定状态的互斥锁,则可以使用{ if (s_FAST_GPU_mutex.try_lock()) { std::lock_guard<decltype(s_FAST_GPU_lock)> guard(s_FAST_GPU_mutex, std::adopt_lock); cv::gpu::FAST_GPU(/*params*/)(/*parameters*/); } else { cv::FAST(/*parameters*/); } } ,如下所示:

<table width="100%" id="table_id">

                        <thead>
                        <tr>
                            <th>Date</th>
                            <th>Salary</th>
                        </tr>
                        </thead>

                        <tfoot>
                        <tr>
                            <th>Date</th>
                            <th>Salary</th>
                        </tr>
                        </tfoot>

                        <tbody>
                            <tr>
                                <td>2011/07/25</td>
                                <td>$170,750</td>
                            </tr>
                            <tr>
                                <td>2009/01/12</td>
                                <td>$86,000</td>
                            </tr>
                            <tr>
                                <td>2011/04/25</td>
                                <td>$320,800</td>
                            </tr>
                            <tr>
                                <td>2011/07/25</td>
                                <td>$170,750</td>
                            </tr>
                            <tr>
                                <td>2009/01/12</td>
                                <td>$86,000</td>
                            </tr>
                        </tbody>
                    </table>