我想在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;
'Semaphore(Semaphore &&)= delete;' –
對不起,我的壞。這只是告訴我,它被隱式刪除。實際的錯誤是我試圖在刪除時使用它。錯誤說「錯誤:使用已刪除的功能...」。所以顯式刪除構造函數會產生相同的錯誤。 –
嘗試'threads.push_back(thread(&Semaphore :: release,std :: ref(sem)));'你想通過引用將'sem'傳遞給線程,但是'std :: thread'通常會嘗試複製它的價值。 –