如何在运行时创建互斥锁

如何在运行时创建互斥锁

本文介绍了如何在运行时创建互斥锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉,这可能是一个愚蠢的问题,但是由于以下问题我已经困扰了很长时间,而我找不到解决方案.我正在使用Boost线程库1.40版.我想创建一个使用互斥量和条件变量来管理读取器和写入器的有界缓冲区.我以库示例为基准,但是我希望能够在运行时创建互斥对象.

我想创建两个FIFO,bufA和bufB. bufA由thrd1(写程序)填充,由thrd2(读程序)消耗.但是,thrd2必须将从bufA读取的数据写入bufB,因此它是bufB的写入器.最后,bufB从thrd3中耗尽.当然,thrd2必须在操作前同时锁定bufA和bufB.但是我不想为bufA和bufB都创建全局互斥锁,因为我希望我的代码可用于任意数量的FIFO.

我的代码如下.请注意,这仅管理单个FIFO,但是如果可以,我将能够容纳它来管理更多的FIFO.我不明白这是怎么回事.

Sorry, probably it is a silly question, but I''ve been stucked for a long time with the following problem and I cannot find the solution. I''m working with boost thread library version 1.40. I want to create a bounded buffer which uses a mutex and conditional variables to manage the reader and writer. I''m followng the library examples as benchmark, but I want to be able to create mutexes objects at runtime.

I want to create two FIFOs, bufA and bufB. bufA is filled by thrd1 (writer) and drained by thrd2 (reader). However, thrd2 has to write the data readed from bufA to bufB, hence it is a writer for bufB. Finally, bufB is drained from thrd3. Of course, thrd2 has to lock both bufA and bufB before his operations. But I don''t want to create global mutexes for both bufA and bufB, since I want my code to work for whatever number of FIFOs.

My code is the following. Note that this manages only a single FIFO, but if it worked I would be able to accomodate it to manage more FIFOs. I cannot understand what is wrong with it.

<pre lang="xml"><br />
/*<br />
fifo_buffer.h<br />
<br />
    Header implementing a mutex FIFO accessible from 2 threads,<br />
    a producer (writer) and a consumer (reader)<br />
*/<br />
<br />
#ifndef _FIFO_BUFFER_H<br />
#define _FIFO_BUFFER_H<br />
<br />
#include <boost/thread/thread.hpp><br />
#include <boost/thread/mutex.hpp><br />
#include <boost/thread/condition.hpp><br />
#include <deque><br />
<br />
#define _ITERS 100<br />
<br />
#ifndef _IO_MUTEX_<br />
#define _IO_MUTEX_<br />
boost::mutex io_mutex;<br />
#endif<br />
<br />
namespace fifo_buffer<br />
{<br />
<br />
    template <class T><br />
    class FifoBuffer<br />
    {<br />
    public:<br />
        typedef boost::mutex::scoped_lock scoped_lock;<br />
<br />
        FifoBuffer(unsigned int buf_size, int id_in, std::deque<T> & buf_in):<br />
            full(0), BUF_SIZE(buf_size), id(id_in), buf(buf_in)//,buf2(buf_in)<br />
        { initialize(); }<br />
<br />
        T get()<br />
        {<br />
            T tmp = buf.front();<br />
            buf.pop_front();<br />
            return tmp;<br />
        }<br />
        void put(const T &m ){buf.push_back(m);}<br />
<br />
        void initialize()<br />
        {<br />
            buf.clear();<br />
            //buf2.clear();<br />
        }<br />
        unsigned int full, BUF_SIZE;//, full2, BUF2_SIZE;<br />
        int id;//, id2;<br />
        std::deque<T> &buf;//, &buf2;<br />
    };<br />
<br />
    template <class T><br />
    class MutexFifo: FifoBuffer<T><br />
    {<br />
    public:<br />
<br />
        MutexFifo(unsigned int buf_size, int id_in, std::deque<T> & buf_in): FifoBuffer(buf_size,id_in,buf_in) {}<br />
<br />
        int getId(){return id;}<br />
<br />
        void push(const T &m)<br />
        {<br />
            scoped_lock lock(mutex);<br />
            if (full == BUF_SIZE)<br />
            {<br />
                {<br />
                    boost::mutex::scoped_lock lock(io_mutex);<br />
                    std::cout << id << ": Buffer is full. Waiting..." << std::endl;<br />
                }<br />
                while (full == BUF_SIZE)<br />
                    cond.wait(lock);<br />
            }<br />
            this->put(m);<br />
            ++full;<br />
            cond.notify_one();<br />
        }<br />
<br />
        T pop()<br />
        {<br />
            scoped_lock lk(mutex);<br />
            if (full == 0)<br />
            {<br />
                {<br />
                    scoped_lock lock(io_mutex);<br />
                    std::cout << id << ": Buffer is empty. Waiting..." <<std::endl;<br />
                }<br />
                while (full == 0)<br />
                    cond.wait(lk);<br />
            }<br />
            T i = this->get();<br />
            --full;<br />
            cond.notify_one();<br />
<br />
            return i;<br />
        }<br />
<br />
    private:<br />
        boost::mutex mutex;<br />
        boost::condition cond;<br />
    };<br />
<br />
}<br />
#endif</pre><br />
<br />
<pre lang="xml"><br />
<br />
// main -- main.cpp<br />
<br />
#include <iostream><br />
#include <boost/thread/thread.hpp><br />
#include <boost/thread/mutex.hpp><br />
#include <boost/bind.hpp><br />
#include "fifo_buffer.h"<br />
#include <deque><br />
<br />
#ifndef _IO_MUTEX_<br />
#define _IO_MUTEX_<br />
boost::mutex io_mutex;<br />
#endif<br />
<br />
using fifo_buffer::FifoBuffer;<br />
using fifo_buffer::MutexFifo;<br />
<br />
<br />
typedef std::deque<int> FIFO;<br />
<br />
void writer(MutexFifo<int> & buffer)<br />
{<br />
        for (register int n = 0; n < _ITERS; ++n)<br />
        {<br />
            {<br />
                boost::mutex::scoped_lock lock(io_mutex);<br />
                std::cout << "sending " << buffer.getId() << ": " << n << std::endl;<br />
            }<br />
            buffer.push(n);<br />
        }<br />
    }<br />
<br />
//template <class T><br />
void reader(MutexFifo<int> & buffer)<br />
    {<br />
        for (register int m = 0; m < _ITERS; ++m)<br />
        {<br />
            //T n = buffer_r.pop();<br />
            int n = buffer.pop();<br />
            {<br />
                boost::mutex::scoped_lock lock(io_mutex);<br />
                std::cout << "received " << buffer.getId() << ": " << n << std::endl;<br />
            }<br />
        }<br />
    }<br />
<br />
<br />
int main()<br />
{<br />
<br />
    FIFO fifo1;<br />
    MutexFifo<int> buffer(10,1,fifo1);<br />
<br />
    boost::thread thrd1(boost::bind(&reader,buffer));<br />
    boost::thread thrd2(boost::bind(&writer,buffer));<br />
<br />
    thrd1.join();<br />
    thrd2.join();<br />
<br />
    return 0;<br />
}</pre><br />
<br />
<br />
<br />

推荐答案


这篇关于如何在运行时创建互斥锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 06:27