2016-07-19 46 views
0

我想在C++ 11中实现计数信号量。这是我的审判......在C++中使用condition_variable实现信号量11

#include <iostream> 
#include <thread> 
#include <mutex> 
#include <future> 
#include <vector> 
using namespace std; 

class Semaphore{ 
private: 
    int count; 
    condition_variable cv; 
    mutex mtx; 

public: 

    Semaphore(int count_):count(count_){} 
    void take(){ 
    unique_lock<mutex> lck(mtx); 
    while(count == 0) 
     cv.wait(lck); 
    count--; 
    cout << "Take\n"; 
    } 
    void release(){ 
    unique_lock<mutex> lck(mtx); 
    count++; 
    cout << "Release\n"; 
    cv.notify_one(); 
    } 

}; 
int main() { 
    Semaphore sem(5); 

    vector<thread> threads; 
    for(int i = 0; i < 10; i++){ 
    threads.push_back(thread(&Semaphore::release, sem)); 
    } 
    for(int i = 0; i < 10; i++){ 
    threads.push_back(thread(&Semaphore::release, sem)); 
    } 
    for(int i = 0; i < threads.size(); i++) 
     threads[i].join(); 
    return 0; 

} 

然而,编译时,它与下面的错误而失败......

note: 'Semaphore::Semaphore(Semaphore&&)' is implicitly deleted because the default definition would be ill-formed: 
    class Semaphore{ 

我最好的猜测是,这是因为使用condition_variable类里面的,它既不可复制也不可移动,因此当它作为参数传递给std :: thread时会引发问题。但是,我不知道如何解决这个问题。任何线索?

更新: 这是完全错误日志...

In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:55:0, 
       from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/thread:39, 
       from /Users/emostafa/Desktop/cpp/A.cpp:2: 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple: In instantiation of 'constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(_UHead&&) [with _UHead = Semaphore; long unsigned int _Idx = 1ul; _Head = Semaphore]': 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:369:49: required from 'constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head>&&) [with long unsigned int _Idx = 1ul; _Head = Semaphore]' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:1162:12: required from 'struct std::__is_nt_constructible_impl<std::_Tuple_impl<1ul, Semaphore>, std::_Tuple_impl<1ul, Semaphore>&&>' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:137:12: required from 'struct std::__and_<std::is_constructible<std::_Tuple_impl<1ul, Semaphore>, std::_Tuple_impl<1ul, Semaphore>&&>, std::__is_nt_constructible_impl<std::_Tuple_impl<1ul, Semaphore>, std::_Tuple_impl<1ul, Semaphore>&&> >' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:1174:12: required from 'struct std::is_nothrow_constructible<std::_Tuple_impl<1ul, Semaphore>, std::_Tuple_impl<1ul, Semaphore>&&>' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:1205:12: required from 'struct std::__is_nothrow_move_constructible_impl<std::_Tuple_impl<1ul, Semaphore>, true>' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:1211:12: required from 'struct std::is_nothrow_move_constructible<std::_Tuple_impl<1ul, Semaphore> >' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/type_traits:137:12: required from 'struct std::__and_<std::is_nothrow_move_constructible<std::_Mem_fn<void (Semaphore::*)()> >, std::is_nothrow_move_constructible<std::_Tuple_impl<1ul, Semaphore> > >' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:218:7: required from 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head, _Tail ...>&&) [with long unsigned int _Idx = 0ul; _Head = std::_Mem_fn<void (Semaphore::*)()>; _Tail = {Semaphore}]' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1559:41: required from 'typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = void (Semaphore::*)(); _Args = {Semaphore&}; typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type = std::_Bind_simple<std::_Mem_fn<void (Semaphore::*)()>(Semaphore)>]' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/thread:142:59: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Semaphore::*)(); _Args = {Semaphore&}]' 
/Users/emostafa/Desktop/cpp/A.cpp:37:54: required from here 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:115:42: error: use of deleted function 'Semaphore::Semaphore(Semaphore&&)' 
    : _M_head_impl(std::forward<_UHead>(__h)) { } 
             ^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: note: 'Semaphore::Semaphore(Semaphore&&)' is implicitly deleted because the default definition would be ill-formed: 
class Semaphore{ 
    ^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: error: use of deleted function 'std::condition_variable::condition_variable(const std::condition_variable&)' 
In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/future:41:0, 
       from /Users/emostafa/Desktop/cpp/A.cpp:4: 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/condition_variable:81:5: note: declared here 
    condition_variable(const condition_variable&) = delete; 
    ^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: error: use of deleted function 'std::mutex::mutex(const std::mutex&)' 
class Semaphore{ 
    ^
In file included from /Users/emostafa/Desktop/cpp/A.cpp:3:0: 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/mutex:129:5: note: declared here 
    mutex(const mutex&) = delete; 
    ^
In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:55:0, 
       from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/thread:39, 
       from /Users/emostafa/Desktop/cpp/A.cpp:2: 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple: In instantiation of 'constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const _Head&) [with long unsigned int _Idx = 1ul; _Head = Semaphore]': 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:357:21: required from 'constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(const _Head&) [with long unsigned int _Idx = 1ul; _Head = Semaphore]' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:206:44: required from 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 0ul; _Head = std::_Mem_fn<void (Semaphore::*)()>; _Tail = {Semaphore}]' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:606:30: required from 'constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) [with _T1 = std::_Mem_fn<void (Semaphore::*)()>; _T2 = Semaphore]' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1510:72: required from 'std::_Bind_simple<_Callable(_Args ...)>::_Bind_simple(_Tp&&, _Up&& ...) [with _Tp = std::_Mem_fn<void (Semaphore::*)()>; _Up = {Semaphore&}; _Callable = std::_Mem_fn<void (Semaphore::*)()>; _Args = {Semaphore}]' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/functional:1559:41: required from 'typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = void (Semaphore::*)(); _Args = {Semaphore&}; typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type = std::_Bind_simple<std::_Mem_fn<void (Semaphore::*)()>(Semaphore)>]' 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/thread:142:59: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Semaphore::*)(); _Args = {Semaphore&}]' 
/Users/emostafa/Desktop/cpp/A.cpp:37:54: required from here 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/tuple:108:25: error: use of deleted function 'Semaphore::Semaphore(const Semaphore&)' 
     : _M_head_impl(__h) { } 
         ^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: note: 'Semaphore::Semaphore(const Semaphore&)' is implicitly deleted because the default definition would be ill-formed: 
class Semaphore{ 
    ^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: error: use of deleted function 'std::condition_variable::condition_variable(const std::condition_variable&)' 
In file included from /usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/future:41:0, 
       from /Users/emostafa/Desktop/cpp/A.cpp:4: 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/condition_variable:81:5: note: declared here 
    condition_variable(const condition_variable&) = delete; 
    ^
/Users/emostafa/Desktop/cpp/A.cpp:9:7: error: use of deleted function 'std::mutex::mutex(const std::mutex&)' 
class Semaphore{ 
    ^
In file included from /Users/emostafa/Desktop/cpp/A.cpp:3:0: 
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/mutex:129:5: note: declared here 
    mutex(const mutex&) = delete; 
+0

'Semaphore(Semaphore &&)= delete;' –

+1

对不起,我的坏。这只是告诉我,它被隐式删除。实际的错误是我试图在删除时使用它。错误说“错误:使用已删除的功能...”。所以显式删除构造函数会产生相同的错误。 –

+2

尝试'threads.push_back(thread(&Semaphore :: release,std :: ref(sem)));'你想通过引用将'sem'传递给线程,但是'std :: thread'通常会尝试复制它的价值。 –

回答

0

你传递sem对象作为thread构造。这就要求它被复制,这就是“使用已删除的函数”所指的内容。

如果你想要一个线程,任务,异步上下文......来引用你的信号量,可以通过std::ref(sem)来传递它,或者回退到普通的旧指针并传递它的地址:&sem

+0

非常感谢!这工作!我记得我之前尝试过,但由于另一个bug,它失败了,所以我认为std :: ref不是问题,但现在尝试它后,它的工作原理:) –