C ++创建原子函数

时间:2012-09-13 13:58:30

标签: c++ multithreading pointers mutex atomic

void foo ( Bar* bar , void(Bar::*qux)(void) )
{
    if ( bar )
    {
        bar->qux();
    }
}

问题是:

  1. bar可以在之后通过其他帖子进行检查后删除。

  2. 我无法向Bar添加互斥锁成员以锁定它。

  3. 因此我想知道,如果我可以告诉处理器以原子方式运行此函数,我该怎么做?我花了很多时间在Google上,但发现没有可理解的手册......

    P.S。 Debian,gcc,Boost NOT 允许,C ++ 11 IS 允许。

5 个答案:

答案 0 :(得分:4)

您可能希望使用具有共享所有权语义的智能指针(例如shared_ptrintrusive_ptr),以确保只要您引用该对象,该对象就会保持活动状态。

答案 1 :(得分:4)

您希望暂时共享对象的所有权,以防止其他线程删除它。这是shared_ptr的作业,当我们不需要访问时,使用weak_ptr允许删除:

void foo ( std::weak_ptr<Bar> weak_bar , void(Bar::*qux)(void) ) 
{
    if (std::shared_ptr<Bar> bar = weak_bar.lock())
    {
        // We now share ownership of the object - it won't be deleted
        bar->qux();
    }

    // We have released ownership - it can now be deleted
}

当然,如果多个线程需要访问该对象,您仍然需要同步;这只能解决问题中指定的删除问题。

答案 2 :(得分:2)

原子方法的概念在C ++中并不像在Java中那样存在,您可以在其中将方法定义为synchronized。你可以在C ++中最接近的是创建一个ScopedMutex类,如下所示:

class ScopedMutex {
public:
    ScopedMutex(pthread_mutex *m) : theMutex_(m) {pthread_mutex_lock(theMutex_);}
    ~ScopedMutex() { pthread_mutex_unlock(theMutex_); }
    // Add appropriate copy constructors and operator=() to disallow mutex copy
    // Or consider passing in a reference
private:
    pthread_mutex *theMutex_;
};

然后在你的函数中使用它:

void foo ( Bar* bar , void(Bar::*qux)(void) )
{
    ScopedMutex m(&aMutex); // This mutex must be defined/initialized elsewhere

    if ( bar )
    {
        bar->qux();
    }

    // The ScopedMutex goes out of scope when the function does,
    // thus releasing the lock
}

但除非你在使用bar对象的其他方法中使用相同的互斥锁,否则这对你没有任何好处。

当你有一个具有复杂逻辑的函数时,当有多个return语句时,Scoped Mutex特别有用,所以你不必手动解锁互斥锁,当函数超出范围时它将被解锁。

答案 3 :(得分:1)

抱歉,但没有。 C ++没有任何东西可以支持它。您不一定需要将互斥锁添加到Bar,但为了避免它,您可能需要Bar周围的包装,或该订单上的某些内容。

答案 4 :(得分:0)

我也要求在Thread-1中以原子方式执行2个函数。

主线程:

   CMythread* pThread = GetThreadFromPool();
   //allocate work to thread
   pThread->ResumeThread();

主题-1:

 AddtoThreadPool(this);
 SuspendThread(); //sleep infinitely unless awakened by Main Thread

问题:      主线程可以在暂停之前恢复池中的线程      和Thread-1(池线程)可以无限地挂起自己。

解决方案:      1.原子地执行Thread-1中的2个函数。没有多少保护可行。      2.定期检查线程池以恢复已分配工作的挂起线程。

感谢您的回答。

的Ajay