2016-07-19 26 views
0

Ich versuche, ein Zähl-Semaphor in C++ 11 zu implementieren. Dies ist mein Versuch ...Semaphore-Implementierung mit condition_variable in C++ 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; 

} 

jedoch beim Kompilieren, es mit dem folgenden Fehler ist Fehler ...

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

Meine beste Vermutung ist, dass dies wegen der condition_variable innerhalb einer Klasse verwendet wird, was weder kopierbar noch beweglich ist, verursacht also ein Problem, wenn es als Parameter an std :: thread übergeben wird. Ich habe jedoch keine Ahnung, wie ich das beheben kann. Irgendwelche Hinweise?

Update: Dies ist die vollständige Fehlerprotokoll ...

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 &&) = löschen;' –

+1

Sorry, mein Schlechter. Das ist nur ein Hinweis, dass es implizit gelöscht wurde. Der eigentliche Fehler ist, dass ich versuche, es zu verwenden, während es gelöscht wird. Der Fehler sagt "Fehler: Verwendung der gelöschten Funktion ...". Das explizite Löschen des Konstruktors führt zu den gleichen Fehlern. –

+2

Probieren Sie 'threads.push_back (thread (& Semaphore :: release, std :: ref (sem)));' Sie möchten 'sem' als Verweis an den Thread übergeben, aber 'std :: thread 'würde normalerweise versuchen zu kopieren es nach Wert. –

Antwort

0

Sie geben das sem Objekt als Wert zum thread Konstruktor. Dies erfordert, dass es kopiert wird, worauf sich die "Verwendung der gelöschten Funktion" bezieht.

Wenn Sie möchten, dass ein Thread, Aufgabe, asynchrone Kontext, ... einen Verweis auf Ihr Semaphor haben, übergeben Sie es entweder durch std::ref(sem), oder fallen Sie zurück auf einfache alte Zeiger und übergeben Sie die Adresse: &sem.

+0

Vielen Dank! Das funktioniert! Ich erinnere mich, dass ich es vorher versucht habe, aber es war wegen eines anderen Fehlers fehlgeschlagen, also dachte ich, dass std :: ref kein Problem ist, aber nachdem ich es jetzt getestet habe, funktioniert es :) –