使用互斥锁锁定矢量 - 增强

时间:2013-10-22 09:25:33

标签: c++ multithreading class boost vector

我正在为路由器编写代码,我希望在收到我的接收器线程上的数据包之后,存储该数据包(类型为" unsigned char *"截至目前)在向量中。我有两个链接到两个不同接口的接收器线程,如果另一个线程已经不能访问该向量,接收器线程应该只存储接收的数据包。

除了两个接收线程之外,我将有一个主线程处理数据包和两个发送线程,每个接口一个。总线程数为5.为防止不同线程正在写入或从向量中读取时出现问题,我听到了一个互斥锁,据说它应该锁定其他(在这种情况下)线程的向量,直到线程之后有问题的是从矢量中读取或写入。

我想知道的是如何将其处理成代码。非常感谢一些例子。我对C ++,Boost和Raw Sockets都很陌生。最重要的是,我不太喜欢在C ++中使用不同的类。我非常清楚它们如何在Java和C#中工作,但我发现的是C ++是非常不同的(因为头文件)。我将所有代码都放在一个巨大的主类中,这可能不是很好的编码风格,但这就是它现在的工作原理。

我应该创建一个类(.h和.cpp文件)来处理这个向量,或者我应该在我的巨型主类中实现它,如果是这样的话,我会很高兴看到一些简单的例子。下面是我希望我的程序如何工作的示例。我已经安装了RecvThread,并且能够打印出数据包的MAC Hdr。

void RecvThread()
{
    //receive a packet


    while(true)
    {
        //get lock status from vector

        if(vector is locked)
        {
            usleep(10000);
        }
        else
        {
            //lock vector
            //save packet in vector
            //unlock vector
        }
    }
}

void SendThread()
{
    while(true)
    {
        //get lock status from vector

        if(vector is locked)
        {
            usleep(10000);
        }
        else
        {
            //lock vector
            //get packet from vector
            //unlock vector
        }
    }

    //send the packet
}

void MainThread()
{

    while(true)
    {
        if(recv vector is empty)
        {
            usleep(10000);
        }
        else if(recv vector is locked)
        {
            usleep(10000);
        }
        else
        {
            //lock recv vector
            //get packet in front of queue
            //unlock recv vector
            //process packet (update different fields)
            //get packet interface (either 1 or 2)
            if(send vector (matching interface) is locked)
            {
                usleep(10000);
            }
            else
            {
                //lock send vector (matching interface)
                //save packet to send vector (matching interface)
                //unlock send vector (matching interface)
            }
        }
    }
}

int main()
{
    //create Recv vector
    //create Send vector 1 and 2 (one for each interface)
    //create and join RecvThread 1 and 2
    //create and join SendThread 1 and 2
    //create and join MainThread
}

1 个答案:

答案 0 :(得分:4)

希望这会给你一个想法。没有测试它,因为它显然不完整:) 键是boost::lock_guard<boost::mutex> lock(mx_);,因为此行一次只能由一个线程执行。实际发生的是线程A例如调用此函数,因为它是第一个到达那里的线程boost::lock_guard<boost::mutex> lock(mx_);立即返回,并且线程可以进入所谓的临界区(代码段之后)锁)。基本上boost::lock_guard<boost::mutex> lock(mx_);仅在临界区内没有其他线程时返回。如果临界区已被另一个线程访问,boost::lock_guard<boost::mutex> lock(mx_);根本不会返回,直到另一个线程离开临界区。为了使等待线程立即继续,需要解锁互斥锁。在boost中,一旦阻塞线程(第一个进入该部分)离开具有临界区的函数范围,这将自动完成。离开范围会破坏变量mx_,从而允许创建并锁定另一个具有相同名称的互斥锁。

编辑:你没有专门锁定一个变量,如矢量。您可以锁定访问该变量的代码段。

class Receiver{
private:
  boost::mutex mx_;
  int *data_;   // I need protection

public:
  bool receive_data(){
    // Prepare connection and do some stuff...

    void some_function(){
      // Before we access data_, we need to make sure only the current thread does so.
      // Mutex will unlock once the scope of this function is left
      boost::lock_guard<boost::mutex> lock(mx_); 

      // Access data_ here (mutex is locked)
      //....
    } // End of scope and mutex unlocks automatically since it's destroyed
    return true;  // Will unlock the mutex since the function's scope is left. 
  }
};