C++에서 개체에 뮤텍스를 사용하는 방법을 이해하려고합니다.개체와 뮤텍스
struct Rope{
int n, steps, offset;
//std::mutex mut;
Rope() {}
Rope(int n, int steps, int offset) : n(n), steps(steps), offset(offset) {}
void compute(){
double a[n];
for (int i=0; i<n; i++)
a[i] = i + offset;
for (int step=0; step<steps; step++)
for (int i=0; i<n; i++)
a[i] = sin(a[i]);
}
};
void runTest(){
int numRuns = 30;
int n = 10000;
int steps = 10000;
std::vector<Rope> ropes;
std::vector<std::thread> threads;
for (int i=0; i<numRuns; i++)
ropes.push_back(Rope(n, steps, i));
for (auto& r : ropes)
threads.push_back(std::thread(&Rope::compute, r));
for (std::thread& t : threads)
t.join();
}
코드는 그대로 잘 실행, 내 4 코어 머신에서 ~ 4 배의 속도 향상을보고 : 나는 속도 테스트로 사용하고 다음 (사소한) 멀티 스레드 코드가 있습니다. 나는 물론 로프에 아무것도 저장하지 않으므로 뮤텍스가 필요하지 않습니다. 지금 내가 보호해야 할 데이터가 있다고 가정한다면, Rope에 뮤텍스를 첨부하고 (예) compute() 루프 내에서 std :: lock_guard를 호출하고 싶습니다. 하지만 mutex의 주석을 제거하면 할당 및 복사 연산자에 "삭제 된 함수 사용"에 대한 컴파일러 오류가 발생합니다. 내가 목표물을 안전하게 잠그기 위해 무엇을 놓치고 있습니까?
@MikeSeymour 그가 말하는 것에 대해 오해하지 않았다면, 그는 모든 스레드에서 ** 같은 ** 뮤텍스를 사용해야합니다. 이동 의미를 사용하여 컨테이너에 넣는 것은 효과가 없습니다. (반면에 현재 쓰여지는 것처럼 각 스레드는 자체적 인'Rope' 객체를 가지므로 뮤텍스는 필요하지 않습니다. 문제가 명확하게 설명되지 않았을 때 정확한 해결책이 무엇인지 말하기는 어렵습니다.) –
@ Mike Seymour :'std :: mutex'는 움직일 수 없습니다. 'Rope'은 기본적으로'Rope' 생성자마다'std :: mutex'를 구성하여 이동 가능하거나 복사 가능하게 만들 수 있습니다. 또는 James가 암시하는 것처럼 뮤텍스를 정적으로 만드는 것입니다. 이 두 가지 접근법 중 적절한 것은 OP만이 시점에서 알고있는 것입니다. –
내 실수. 게시하기 전에 내 가정을 확인 했어야합니다. –