여러 생산자/소비자 및 중요한 섹션 코드 문제
-
05-07-2019 - |
문제
C에서 여러 생산자/소비자 문제를 시도하고 있지만 예상대로 작동하지 않습니다. 다음은 내 구현을 나타내는 의사 코드입니다.
Thread thread1;
Thread thread2;
Thread thread3;
Data data1;
Mutex data1_mutex;
Semaphore data1_empty;
Semaphore data1_fill;
Data data2;
Mutex data2_mutex;
Semaphore data2_empty;
Semaphore data2_fill;
thread1()
{
// creates data and places it into data1.
wait(data1_empty);
lock(data1_mutex);
// critical section
unlock(data1_mutex);
post(data1_fill);
}
thread2()
{
// Removes data from data1, processes it, and places it into data2.
// data1
wait(data1_fill);
lock(data1_mutex);
// data2
wait(data2_empty);
lock(data2_mutex);
// critical section
// data2
unlock(data2_mutex);
post(data2_fill);
// data1
unlock(data1_mutex);
post(data1_empty);
}
thread3()
{
// Removes data from data2, prints its results, and removes it.
wait(data2_fill);
lock(data2_mutex);
// critical section
unlock(data2_mutex);
post(data2_empty);
}
그러나이 솔루션을 사용하면 Data1이 채워 지지만 Thread2는 잠그고 실행되지 않습니다. 내 구현에 문제가 있습니까?
#1 편집
내가 찾은 문제 중 하나는 두 번째 뮤트가 올바르게 만들어지지 않았다는 것입니다. 나는 그것에 무엇이 잘못되었는지 모르기 때문에 모든 스레드에 대한 첫 번째 뮤트를 사용하고 있습니다. 작동하도록하기 위해 한 다른 일이 있으므로 나중에 1 분이있을 때이를 반영하기 위해 의사 코드를 업데이트하겠습니다.
해결책
게시한지 확인하십시오 data1_empty
그리고 data2_empty
처음에.
다른 팁
어떤 종류의 대기열 유형을 사용하는 경우 Data
, 당신은 각각의 Data
큐 깊이는 엄격하게 0 또는 1입니다. 로컬 변수를 사용하는 경우 thread2
, 중요한 섹션의 크기를 줄일 수 있습니다.
그런 다음 코드는 다음과 같습니다.
thread1() {
//Wait for data to put in the queue (i.e. a blocking socket read)
lock(data1_mutex);
data1.push(someData);
unlock(data1_mutex);
post(data1_fill);
}
thread2() {
DataType dataElement;
wait(data1_fill);
lock(data1_mutex);
dataElement = data1.pop();
unlock(data1_mutex);
lock(data2_mutex);
data2.push(dataElement);
unlock(data2_mutex);
post(data2_fill);
}
thread3() {
DataType dataElement;
wait(data2_fill);
lock(data2_mutex);
dataElement = data2.pop();
unlock(data2_mutex);
//do something with dataElement here
}
Wrang-Wrang의 말은 Data_2_Empty를 기다리는 동안 Data_1의 잠금 장치를 유지하지 않으려 고 노력합니다. 교체하는 Data_1 및 Data_2의 대체 버퍼를 유지하여이를 달성 할 수 있습니다. Thread_2는 data_1을 data_2로 처리하는 동안 data_1을 스왑합니다. Thread_3은 데이터를 처리하는 동안 data_2를 교체합니다. 현재 의사 코드를 사용하면 스레드 1과 스레드 3이 동시에 실행되지만 스레드 2는 다른 것 중 하나와 동시에 실행할 수 없습니다.