2013-08-23 3 views
-1

У меня есть 3 потока, которые могут работать одновременно, теперь я хочу контролировать их бегущую логику, как показано ниже.C++ Как получить статус в многопоточном режиме

1) thread1, thread2, thread3 - 3 вида трудоемкой нити, я хочу только запустить 1 в то время. и thread1 также является эксклюзивным с самим собой, это означает, что если работает один поток1, второй поток1 также не будет работать.

2) Я хочу знать текущую текущую информацию о потоке (например, какой поток работает) , например, когда thread1 запущен, теперь перед запуском thread2 я хочу проверить, существует ли поток , и я также хочу знать, в какой строке работает данный поток (в этом примере я хочу знать, что работает thread1), если есть thead1, я не буду запускать thread2 и возвращать статус.

Основание выше, я определил ниже класс блокировки.

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; 
    } 

} 

в функции потока1 proc, он будет вызывать, как показано ниже. он также будет похож на функцию thread2/thread3 proc, GetInstance() является одноэлементным и получит уникальный глобальный объект.

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; 
} 

После того, как я тестирую, это похоже на работу в порядке. Однако я хочу знать, является ли это стандартным способом для этого. Любые комментарии приветствуются.

------ 2013.8.23 реализация Update CXXXLock --------

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

It кажется, я определил некорректную функцию, которая будет запутана. По моему требованию, похоже, что CXXXXLock :: GetExclusiveFlag вместо функции CXXXLock :: Lock, поскольку он фактически не имеет функции блокировки. и поток должен следовать этой спецификации, прежде чем делать реальные действия.

+12

«Я хочу запускать только 1 в то время». Зачем вам нужно несколько потоков? – Kolyunya

+0

hm, вы можете думать, что есть 3 модуля, и они будут запускать каждый поток, и мы не хотим, чтобы они запускались в одно и то же время.мы не могли контролировать каждый модуль, когда они запустили поток. –

+1

То, что вы делаете, похоже на [WTF] (http://thedailywtf.com/). – Dariusz

ответ

0

- Я хочу работать только 1 в то время

- Зачем вам нужен несколько потоков тогда?

- hm, вы можете думать, что есть 3 модуля, и они будут запускать каждый поток, и мы не хотим, чтобы они запускались в одно и то же время. мы не сможем управлять каждым модулем при запуске потока.

Я могу думать о одной возможной причине, по которой потоки не хотят работать одновременно. Это ситуация, когда они работают на одном и том же общем ресурсе. В этом случае для предотвращения сбоев данных вы можете использовать, например, объект mutex. Thread-1 блокирует mutex, выполняет некоторые операции с общими данными и затем разблокирует его. Thread-2 попытается заблокировать это приглушение и будет ждать, пока поток-1 разблокирует mutex, если он заблокирован.

В комментариях вы упомянули, что вам необходимо синхронизировать несколько типов операций. В этом случае вы должны использовать N объектов mutex для N типов блокировок (операций). Если mutex_1 заблокирован, это означает, что теперь выполняется операция_1. Если mutex_2 заблокирован, это означает, что теперь выполняется операция_2. Если mutex_n не заблокирован, это означает, что операция_n не запущена в настоящее время.

+0

hm, ваш сценарий - одна история, есть еще одна история, например, один поток выполняет сканирование, другой - действие по обновлению, мы не хотим одновременно сканировать и обновлять. и при сканировании, действие «Обновление» просто проверьте его и пропустите обновление на этот раз, это актуально, что нужно делать. Благодаря! –

+0

@ user1337961 sceanrion, о котором вы описали, решается одинаково. Темы, которые должны выполняться отдельно, пытаются получить контроль над общим «mutex». Если они заблокируют его, ни один другой поток не будет выполняться до тех пор, пока первый его не разблокирует. – Kolyunya

+0

Нынешним требованием является то, что другой поток не хочет ждать, просто пропустите его на этот раз. –