저는 C++ boost :: thread 라이브러리를 사용하고 있습니다. 이는 필자가 pthreads를 사용하고 있음을 의미합니다. 공식적으로 뮤텍스는 잠금 장치가있는 동일한 스레드에서 잠금을 해제해야하며 한 스레드에서 잠그고 다른 스레드에서 잠금을 해제 할 수있는 효과가 필요합니다. 이것을 성취 할 수있는 방법은 여러 가지가 있습니다. 한 가지 가능성은이 동작을 허용하는 새로운 뮤텍스 클래스를 작성하는 것입니다. 또 다른 호출) (잠금을 해제하는 동안, 첫 번째 스레드가를 취득 할 수 있습니다 하나 개의 스레드() 잠금을 호출하는 경우 이후모델링 boost :: 뮤텍스가 아닌 세마포어로 잠금 가능 (이전 제목 : 다른 스레드에서 뮤텍스 잠금 해제)
class inter_thread_mutex{
bool locked;
boost::mutex mx;
boost::condition_variable cv;
public:
void lock(){
boost::unique_lock<boost::mutex> lck(mx);
while(locked) cv.wait(lck);
locked=true;
}
void unlock(){
{
boost::lock_guard<boost::mutex> lck(mx);
if(!locked) error();
locked=false;
}
cv.notify_one();
}
// bool try_lock(); void error(); etc.
}
내가, 위의 코드는 FIFO 액세스를 보장하지 않는다는 것을 지적한다 : 예를 들어
대기중인 다른 스레드보다 먼저 잠급니다. (boost :: thread 문서는 뮤텍스 나 조건 변수에 대한 명시적인 스케쥴링 보장을하지 않는 것처럼 보입니다.) 하지만 지금은 (그리고 다른 버그들) 무시하십시오.
제 질문은 제가이 루트로 가기로 결정한 경우, 그러한 뮤텍스를 Lockable 개념의 부스트 모델로 사용할 수 있을지 의문입니다. 예를 들어 RAII 형식의 액세스에 boost::unique_lock< inter_thread_mutex >
을 사용하고 boost::condition_variable_any.wait()
등으로이 잠금을 전달하면 문제가 발생합니다.
한편으로는 왜 보이지 않습니다. 반면에, "왜 안 보이지 않는가?"는 보통 무언가가 효과가 있을지 결정하는 아주 나쁜 방법입니다.
내가 묻는 이유는 RAII 잠금 및 조건 변수에 대한 래퍼 클래스를 작성해야한다는 것이 밝혀지면 다른 어떤 방법으로도 동일한 효과를 얻을 수 있습니다.
편집 : 내가 원하는 행동의 종류는 기본적으로 다음과 같습니다. 객체가 있고 수정할 때마다 잠글 필요가 있습니다. 한 스레드에서 객체를 잠그고 그 객체에 대한 작업을 수행하고 싶습니다. 그런 다음 다른 작업자 스레드가 작업을 완료하도록 지시하는 동안 객체를 잠근 상태로 유지하려고합니다. 그래서 첫 번째 쓰레드는 작업자 쓰레드가 끝나는 동안 계속 진행할 수 있습니다. 작업자 스레드가 완료되면 뮤텍스가 잠금 해제됩니다.
그리고 내가 아무렇지도 않아 스레드 1이 작업을 시작하고 스레드 2가 스레드를 완료 할 때 아무도 뮤텍스 잠금을 얻을 수 없도록 전환을 원합니다.
inter_thread_mutex와 같은 것은 작동하는 것처럼 보이며 프로그램이 일반 뮤텍스처럼 상호 작용할 수도 있습니다. 그래서 그것은 깨끗한 솔루션처럼 보입니다. 더 좋은 해결책이 있다면, 나는 또한 그것을 듣게되어 기쁩니다.
EDIT AGAIN : 잠금이 필요한 이유는 여러 개의 마스터 스레드가 있고 잠금이 잘못된 방법으로 공유 된 개체에 동시에 액세스하지 못하게하기 위해서입니다. 그래서 코드는 이미 마스터 스레드 수준에서 루프 수준의 잠금없는 시퀀싱 작업을 사용합니다. 또한 원래 구현에서는 작업자 스레드가 없었고 뮤텍스는 일반적인 코 셔 뮤텍스였습니다.
inter_thread_thingy는 주로 응답 시간을 향상시키기 위해 최적화 된 것으로 나타났습니다. 많은 경우, 작업 A의 "첫 번째 부분"이 작업 B의 "첫 번째 부분"전에 발생하는 것을 보증하는 것으로 충분했습니다. 멍청한 예를 들어, 개체 1을 펀치하고 검은 눈을 띄게한다고 말합니다. 그런 다음 대상 1에 모든 조직 손상을 반영하도록 내부 구조를 변경하라고 지시합니다. 나는 두 번째 펀치로 이동하기 전에 조직 손상을 기다리고 싶지 않습니다. 그러나 동일한 작업의 일부로 발생하는 조직 손상을 원합니다. 예를 들어, 잠시 동안 다른 스레드가 조직 손상을 잘못된 작업으로 만드는 방식으로 개체를 다시 구성하는 것을 원하지 않습니다.(예,이 예제는 여러 가지면에서 불완전합니다. 그리고 어떤 게임에서도 작동하지 않습니다.)
그래서 우리는 객체 소유권을 작업자 스레드로 전달하여 작업을 완료 할 수있는 모델을 변경했습니다 실제로는 꽤 잘 작동합니다. 각 마스터 스레드는 모두 완료 될 때까지 기다릴 필요가 없으므로 더 많은 작업을 수행 할 수 있습니다. 또한 마스터 스레드 레벨에서의 이벤트 시퀀싱은 여전히 루프 기반이므로 높은 수준의 마스터 스레드 작업을 작성하는 것이 쉽습니다. 작업이 완료되었다는 가정에 기반 할 수 있기 때문입니다 (보다 정확하게는 중요한 " 첫 번째 부분 "이 해당 함수 호출이 반환 될 때 완료됩니다.
마지막으로, 모든 작업을 수행하는 데 필요한 동기화를 캡슐화하기 위해 부스트 잠금이있는 RAII를 사용하여 inter_thread 뮤텍스/세마포어를 사용하는 것이 좋을 것이라고 생각했습니다.
당신의 코드는 작동하지 않습니다. 당신은 여전히 정의되지 않은 동작을 일으키는 다른 스레드로부터 mx를 잠금 해제하고 있습니다. 그러나 세마포는 당신이 원하는 것을 할 것이고, 그것을 찾는다. – hirschhornsalz
사실 나는 코드가 작동한다고 생각합니다. 부스트 잠금은 범위가 지정됩니다. 즉, 파괴시 뮤텍스 잠금을 해제합니다. 따라서 boost :: mutex는 잠긴 동일한 스레드에 의해 해제됩니다. 내부 뮤텍스의 목적은 잠긴 부울에 대한 액세스를 잠그는 것입니다. 그러나 내가 필요한 것은 세마포어입니다. 실제로,이 inter_thread_mutex는 사실 뮤텍스를 호출하는 바이너리 세마포어와 더 비슷합니다. – dan
이 코드는이 훌륭한 SO 답변에서 링크 된 뮤텍스를 사용하여 세마포를 구현하기 위해이 코드와 비슷합니다. http://stackoverflow.com/questions/62814/바이너리 - 세마포어와 뮤텍스 간의 차이/311648 # 311648 세마포어와 뮤텍스의 관계. OP의 질문은 근본적으로, 'unique_lock' 등은 뮤텍스뿐만 아니라 세마포어와 함께 작동합니다. – Potatoswatter