멀티 스레딩에 대해 배우고 있으며 제작자 - 소비자 문제 (이를 호출 할 수있는 경우 세마포어 사용)를 시뮬레이트하고 싶습니다.Segfault가 대기열을 동기화하려고 시도 중임
대기열을 보유하는 클래스가 있고, 생산자가 대기열에 int를 푸시하고 소비자가 가져 와서 인쇄합니다. I 시뮬레이션
class TestClass{
public:
void producer(int i){
unique_lock<mutex> l(m);
q.push(i);
if(q.size())
cnd.notify_all();
}
void consumer(){
unique_lock<mutex> l(m);
while(q.empty()){
cnd.wait(l);
}
int tmp = q.front();
q.pop();
cout << "Producer got " << tmp << endl;
}
void ConsumerInit(int threads){
for(int i = 0; i < threads; i++){
thrs[i] = thread(&TestClass::consumer, this);
}
for(auto &a : thrs)
a.join();
}
private:
queue<int> q;
vector<thread> thrs;
mutex m;
condition_variable cnd;
};
다음으로 내가 호출 작은 콘솔 애플리케이션을 사용하는 데이터 :
int main(){
int x;
TestClass t;
int counter = 0;
while(cin >> x){
if(x == 0)
break;
if(x == 1)
t.producer(counter++);
if(x == 2)
t.ConsumerInit(5);
}
}
그래서 사용자 프레스 2 개 스레드가있는 경우, 사용자 입력 (1), 데이터는 대기열에 가압 될 때 산란했다.
예를 들어, 1을 누른 다음 2를 누르거나 2 1 1 을 누르는 등의 순서로 호출하면 segfault가 throw됩니다. 나는 왜 내 코드에 대한 나의 이해가 다음과 같은지 잘 모르겠다. 2 1 1
5 개의 스레드를 초기화하면 대기열이 비어있어 잠자기 상태가된다. 숫자를 대기열로 보내면 모든 스레드가 대기 중임을 알립니다. 잠긴 뮤텍스를 다시 깨우고 대기열에서 번호를 검색 한 후 뮤텍스를 릴리스하면 뮤텍스가 릴리스 될 때 다른 스레드가 동일한 작업을 수행하고 뮤텍스를 잠금 해제합니다. 뮤텍스가 풀린 후 세 번째 스레드는 계속 루프 상태이며 보입니다. 그 큐는 아직 다시 비어 있고, 나머지 모든 쓰레드와 마찬가지로 다시 잠든다.
이 논리가 맞습니까? 그렇다면 왜 이것이 segfault를 던지는지, 그렇지 않다면 나는 모든 설명에 감사 드린다.
도움 주셔서 감사합니다.
// 편집 대답 suggets에 의해 []를 vector.push_back으로 바꿨지 만 소비자는 데이터를 사용하지 않고 가져 가거나 인쇄하지 않습니다. 당신이
thrs[i] = thread(&CTest::consumer, this);
을 수행 할 때
오타, 감사합니다! 업데이트 됨 – Darlyn
오, 고마워요. 다시 말하면 – Darlyn