-1

I have 3 threads that maybe run at the same time, now I want to control their running logic as below.

1) thread1, thread2, thread3 are 3 kinds of time-consuming thread, I want only run 1 at the time. and thread1 is also exclusive with itself, it means if one thread1 is running, the second thread1 will also not run.

2) I want to know current running thread information, (ex, which kind of thread is running) for example, when thread1 is running, now before run thread2, I want to check current whether there is a thread running, and I also want to know currently which thread is running (in this sample, I want to know thread1 is running), if there is thead1 running, I will not run thread2, and return status.

Base on above, I defined below lock class.

enum LOCK_TYPE{
    Type_UnLock = 0,
    Type_Lock_1,
    Type_Lock_2,
    Type_Lock_3,
};

//uCurLockType is a reference, when locked by others, 
//it will store current lock type and return.
std::unique_lock<std::mutex> g_lock(g_mutex, std::defer_lock);

bool CXXXLock::Lock(LOCK_TYPE uToLockType, LOCK_TYPE& uCurLockType)
{
    if(m_uLockType != LOCK_TYPE::Type_UnLock)
    {
        uCurLockType = m_uLockType;
        return false;
    }
    if(g_lock.try_lock())
    {
        m_uLockType = uToLockType;
        g_lock.unlock();
        return true;
    }
    else
    {
        uCurLockType = m_uLockType;
        return false;
    }
}

bool CXXXLock::Unlock()
{
   if(g_lock.try_lock())
   {
       m_uLockType = LOCK_TYPE::Type_UnLock;
       g_lock.unlock();
       return true;
   }
   else
   {
       return false;
   }

}

in thread1 proc function, it will call as below. it will also similar as thread2/thread3 proc function, GetInstance() is a singleton, and will get the unique global object.

unsigned thread1proc(LPVOID lpParam)
{
    LOCK_TYPE uToLockType = LOCK_TYPE::Type_Lock_1, uCurLockType = LOCK_TYPE::Type_UnLock;
    if(false == GetInstance().Lock(uToLockType, uCurLockType))
    {
        //it is locked by other thead, uCurLockType means which kind of thread lock it.
        //store current lock type uCurLockType and exit this thread.
        return;
    }

    //  do thread logic

    GetInstanct().Unlock();
    return;
}

After I testing, it seems work ok, However, I want to know whether this is standard way to do this. Any comments is appreciated.

------2013.8.23 Update CXXXLock implementation--------

------2031.8.36--------

It seems I have defined some wrong function that will make confused, For my requirement, it seems looks like CXXXXLock::GetExclusiveFlag instead of CXXXLock::Lock function as it has no lock function actually. and the thread should follow this specification before do real action.

4

1 回答 1

0

-- I want only run 1 at the time

-- Why do you need multiple threads then?

-- hm, you can think there are 3 modules, and they will launch each thread, and we do not want to they run at the same time. we could not control each module when they will launch thread.

I can think of one possible reason for threads to want not to run at the same time. It is the situation when they operate on the same shared resource. In that case to prevent data-races you can use for example a mutex object. Thread-1 locks the mutex, performs some operations on shared data and then unlocks it. Thread-2 will try to lock that mutes and will wait for the thread-1 to unlock the mutex if it's locked.

In the comments you've mentioned that you have to synchronize several types of operations. In that case you should use N mutex objects for N types of locks (operations). If mutex_1 is locked that means that operation_1 is running now. If mutex_2 is locked that means that operation_2 is running now. If mutex_n is un-locked that means that operation_n is not running now

于 2013-08-23T08:35:48.257 回答