c ++

时间:2017-05-03 11:13:18

标签: c++ multithreading c++11 mutex

我正在努力让这项工作得以实现,但似乎有些事情我不能完全理解。

我在一个文件中有一个多线程应用程序(2个类和我创建线程和所有内容的真正主要部分)。我想分成3个文件。每个类一个(带有标题),一个用于主。

我有几个mutices和一个队列来在线程之间共享消息并随时锁定和解锁它们。

我想写一个单例类,所以它们都可以共享互斥锁:

头:

#ifndef COMMONSINGLETON_H
#define COMMONSINGLETON_H

#include <mutex>          // std::mutex
#include <queue>

class CommonSingleton{
    private:
        static std::mutex               mutex_w_b;
        //static std::mutex               mutex_wifi_ok;
        //static std::queue <std::string> queue_w_b;

    public:
        static CommonSingleton& getInstance();
        std::mutex GetMutexWB();
        //std::mutex GetMutexWiFiOk();
        //std::queue <std::string> GetQueueWB();
    private:
        CommonSingleton() {};
        CommonSingleton(CommonSingleton const&);
        void operator=(CommonSingleton const&);
};
#endif

我的.cpp文件:

#include "commonsingleton.h"

static CommonSingleton& CommonSingleton::getInstance(){
    static CommonSingleton instance;
    return instance;
}
std::mutex CommonSingleton::GetMutexWB(){
    return mutex_w_b;
}
/*std::mutex CommonSingleton::GetMutexWiFiOk(){
    return mutex_wifi_ok;
}
std::queue <std::string> CommonSingleton::GetQueueWB(){
   return queue_w_b;
}*/

在我的主要内容中,我要测试互斥锁:

CommonSingleton::getInstance().GetMutexWB.lock();

但是现在我已经评论过,只是为了弄清楚如何编译。这是我得到的错误:

commonsingleton.cpp:4:54: error: cannot declare member function ‘static 
CommonSingleton& CommonSingleton::getInstance()’ to have static linkage [-
fpermissive]
static CommonSingleton& CommonSingleton::getInstance(){
                                                  ^
commonsingleton.cpp: In member function ‘std::mutex 
CommonSingleton::GetMutexWB()’:
commonsingleton.cpp:9:12: error: use of deleted function 
‘std::mutex::mutex(const std::mutex&)’
return mutex_w_b;
            ^
In file included from commonsingleton.h:5:0,
from commonsingleton.cpp:1:
/usr/include/c++/4.8/mutex:128:5: error: declared here
mutex(const mutex&) = delete;

我在这里做错了什么?

4 个答案:

答案 0 :(得分:3)

你不需要那么多样板文件。你只需要一个功能:

std::mutex& getCommonMutex() {
    static std::mutex m;
    return m;
}

就是这样,你可以从任何地方调用这个函数,它总是会返回对同一个互斥锁的引用,这个互斥锁将在它第一次被调用时被初始化。

答案 1 :(得分:2)

您有一些编译器错误如下:

首先,您不需要在函数定义中再次编写静态,因此在您的cpp中:

CommonSingleton& CommonSingleton::getInstance(){
    static CommonSingleton instance;
    return instance;
}

其次,std::mutex删除了复制和移动构造函数,因此您无法通过引用(或const-ref)传递现有的互斥锁,而是将cpp函数转换为:

std::mutex& CommonSingleton::GetMutexWB(){
    return mutex_w_b;
}
std::mutex& CommonSingleton::GetMutexWiFiOk(){
    return mutex_wifi_ok;
}

确保您也在声明中更改了这些(.h)

答案 2 :(得分:2)

更有用的单例是客户端程序不知道它是单例的单例。

这意味着如果您希望不进行重构,您可以在以后改变主意。

示例:

#include <mutex>          // std::mutex
#include <iostream>
#include <thread>
#include <chrono>
#include <future>

// Note: This class is a singleton by internal implementation, not
// by interface. This separates the concerns of its function and its
// form, meaning client programs do not need to care.
//
class CommonSingleton{
  using mutex_type = std::mutex;
  using lock_type = std::unique_lock<mutex_type>;

private:
  struct Impl {

    mutex_type mutex_w_b;

    lock_type get_lock() { return lock_type(mutex_w_b); }

  };

  static Impl& get_impl() {
    static Impl impl {};
    return impl;
  }

public:

  lock_type get_lock() {
    return get_impl().get_lock();
  }
};


// note - copyable
void foo(CommonSingleton singleton)
{
  using namespace std::literals;
  for(int i = 0 ; i < 10000 ; ++i) {
    auto lock = singleton.get_lock();
    std::cout << "foo\n";
    lock.unlock();
    std::this_thread::sleep_for(1ms);
  }
}

void bar(CommonSingleton singleton)
{
  using namespace std::literals;
  for(int i = 0 ; i < 10000 ; ++i) {
    auto lock = singleton.get_lock();
    std::cout << "bar\n";
    lock.unlock();
    std::this_thread::sleep_for(1ms);
  }
}

void baz(CommonSingleton singleton)
{
  using namespace std::literals;
  for(int i = 0 ; i < 10000 ; ++i) {
    auto lock = singleton.get_lock();
    std::cout << "baz\n";
    lock.unlock();
    std::this_thread::sleep_for(1ms);
  }
}

int main()
{
  // all using the same mutex in reality...
  auto ffoo = std::async(std::launch::async, foo, CommonSingleton());
  auto fbar = std::async(std::launch::async, bar, CommonSingleton());
  auto fbaz = std::async(std::launch::async, baz, CommonSingleton());

  ffoo.wait();
  fbar.wait();
  fbaz.wait();
}

答案 3 :(得分:1)

关键字static在c ++中有许多不同的含义。当你在类成员声明中使用它时,你将类成员声明为static,但是当你在.cpp文件中的类成员定义中使用它时,你强制它上面的静态链接(虽然它应该有外部链接可用于不同的翻译单位)。

所以在.cpp文件中你应该改变

static CommonSingleton& CommonSingleton::getInstance(){

CommonSingleton& CommonSingleton::getInstance(){