부스트와 같은 최신 C++ 스레딩 라이브러리에 대한 액세스 권한이없는 프로젝트에 다음 코드를 생성했습니다. 내 바램은 범위를 벗어나 자물쇠가 자동으로 해제되도록하는 것입니다.수제 범위 잠금이 잠기지 않습니다.
공유 잠금이 정상적으로 작동합니다. 스레드가 스레드를 획득하면 첫 번째 스레드가 스레드를 해제 할 때까지는 다른 스레드가이를 획득 할 수 없습니다. Scoped는 작동하지 않습니다.
다음은 출력의 의미를 보여줍니다. 나는 각각의 쓰레드에 고유 한 이름을 주었고, 동일한 공유 잠금을 사용하여 Scoped 자물쇠를 인스턴스화하고, '획득'을 인쇄하고, 5 초 동안 자고, '릴리스'를 인쇄 한 다음 범위를 벗어났다. 획득/릴리스 쌍을 얻는 대신에, 나는 4 년 동안 획득 한 것을 5 년 간격으로 빠르게 연속해서 얻는다. Scoped의 잠금 장치를 포인터로 변경하고 획득하기 전에 주소를 인쇄하여 미쳐 있지 않은지 확인했습니다. 동일한 Shared 객체 인 것처럼 보이지만 잠금은 다중 액세스를 방지하지 못합니다.
Lock '140734928395200'.
acquired: !!!!!
Lock '140734928395200'.
acquired: -------
Lock '140734928395200'.
acquired: ***************
Lock '140734928395200'.
acquired: ##
released: !!!!!
released: -------
released: ***************
released: ##
여기 Lock.h의 소스 코드입니다 :
#include <pthread.h>
namespace Lock
{
class Shared
{
public:
Shared()
{
::pthread_mutex_init(&(this->mutex), nullptr);
}
~Shared()
{
}
void acquire()
{
::pthread_mutex_lock(&(this->mutex));
}
void release()
{
::pthread_mutex_unlock(&(this->mutex));
}
private:
pthread_mutex_t mutex;
};
class Scoped
{
public:
Scoped(Lock::Shared& lock) : lock(lock)
{
this->lock.acquire();
}
virtual ~Scoped()
{
this->lock.release();
}
private:
Lock::Shared& lock;
};
};
여기 테스트를 위해 내 main.cc 파일입니다. 나는 다음과 함께 건물을 짓고있다 :
g++ -std=c++11 -o try -pthread main.cc && ./try
g ++ 4.7 최신 우분투 시스템.
#include <pthread.h>
#include <iostream>
#include "Lock.h"
#include <unistd.h>
struct data
{
data(std::string name, Lock::Shared& lock) : name(name), lock(lock) { ; }
std::string name;
Lock::Shared& lock;
};
void* doStuff(void* v)
{
data* d = (data*)v;
for (int i = 0; i < 5; i++)
{
Lock::Scoped(d->lock);
//d->lock->acquire();
std::cout << "acquired: " << d->name << std::endl;
::sleep(5);
std::cout << "released: " << d->name << std::endl;
//d->lock->release();
::sleep(1);
}
}
int main(int argc, char* argv[])
{
pthread_t fred;
pthread_t barney;
pthread_t wilma;
pthread_t betty;
Lock::Shared lock;
data f("##", lock);
data b("***************", lock);
data w("-------", lock);
data e("!!!!!", lock);
::pthread_create(&fred, nullptr, doStuff, (void*)&f);
::pthread_create(&barney, nullptr, doStuff, (void*)&b);
::pthread_create(&wilma, nullptr, doStuff, (void*)&w);
::pthread_create(&betty, nullptr, doStuff, (void*)&e);
::pthread_join(fred, nullptr);
::pthread_join(barney, nullptr);
::pthread_join(wilma, nullptr);
::pthread_join(betty, nullptr);
return 0;
}
합니다. 두 가지 제안 : (1) 우리가 실험 할 수있는 완전한 실행 가능한 예제를 게시하십시오. (2) pthreads 함수의 값을 무시하지 않고 검사합니다. – NPE
출력 버퍼링이 가능합니까? – hmjd
@hmjd : 없어야합니다. std :: endl 버퍼를 플러시합니다. – kwiqsilver