2016-06-09 5 views
1

Angenommen, ich eine Schnittstelle, die eine gewisse Menge von Zahlen foo und führt einige Permutation bar auf sie nimmt:Wie kann ich die Thread-Sicherheit von Parametern in einer Schnittstelle anfordern?

class Interface 
{ 
public: 
    virtual std::vector<double> PerformBar(const std::vector<double>& foo) = 0; 
    virtual void SetBar(std::function<double(double)>&& func) = 0; 
}; 

Wenn die Implementierung waren Single-Thread, es wäre kein Problem, aber was ist, wenn meine Implementierung Versuche parallelisieren seine Aufgabe?

class Impl final : public Interface 
{ 
public: 
    std::vector<double> PerformBar(const std::vector<double>& foo) override 
    { 
    std::vector<double> result(foo.size()); 
    std::thread t1([&]() 
     { 
     for (int i = 0; i != foo.size()/2; ++i) 
      result[i] = bar(foo[i]); 
     }); 

    std::thread t2([&]() 
     { 
     for (int i = foo.size()/2; i != foo.size(); ++i) 
      result[i] = bar(foo[i]); 
     }); 

    t1.join(); 
    t2.join(); 

    return result; 
    } 

    void SetBar(std::function<double(double)>&& func) override 
    { 
    bar = func; 
    } 

private: 
    std::function<double(double)> bar; 
}; 

Derzeit meine Schnittstelle macht es nicht klar für den Benutzer, dass func Thread-sicher sein sollte, noch es erzwingt, dass die Umsetzung annimmt, dass es ist nicht Thread-sicher.

Anders als das Hinzufügen von Kommentaren, wie kann ich meine Schnittstelle ändern, um sicherzustellen, dass der Benutzer versteht, dass func Thread-sicher sein muss?

+0

Es gibt keine afaik solche Option. Ich würde einen richtigen Kommentar in der Nähe der Funktionsdeklaration geben. –

+0

Durch Umbenennen in 'PerformParallellBar'? – Jarod42

+0

Das hört sich so an, als müsste es in der Dokumentation behandelt werden. Ein hacky Weg, wie Sie es tun könnten, ist die Funktion eine Vorlage und dann benennen Sie die Funktion 'SomeThreadSafeFunctionThatTakesAndReturnsDouble' – NathanOliver

Antwort

1

Hier ist eine Art und Weise (abgesehen von der offensichtlichen Dokumentation) btw - das ist eine Skizze, nicht kompilieren Code ..

template <typename MutexType> 
class Interface { 
public: 
    std::vector<double> PerformBar(const std::vector<double>& foo) { 
    // Lock the mutex 
    return DoPerformBar(foo); 
    } 

    void SetBar(std::function<double(double)>&& func) { 
    // Lock the mutex 
    return DoSetBar(forward(func)); 
    } 

protected: 
    virtual std::vector<double> DoPerformBar(const std::vector<double>& foo) = 0; 
    virtual void DoSetBar(std::function<double(double)>&& func) = 0; 

private: 
    MutexType mutex_; 
}; 

class SingleThreadedImpl final : public Interface<boost::interprocess::null_mutex> 
{ 
protected: 
    // Do the protected methods 
}; 

class ParallelImpl final : public Interface<std::mutex> 
{ 
protected: 
    // Do the protected methods 
}; 
Verwandte Themen