이유와 함께 기다리는 세마포는 부모 프로세스가 (자식 프로세스 당 하나씩) 명명되지 않은 세마포 배열을 사용하여 계속하기 전에 여러 자식 프로세스가 대기하는 것을 기다리고 있습니다. 그러나 sem_wait()를 사용할 때 부모 프로세스는 무한정 기다리고 sem_trywait()는 "리소스를 일시적으로 사용할 수 없음"오류를 반환하고 자식 프로세스가 신호를 보내지 않고 계속합니다. sem_init() 또는 sem_post()는 오류를 반환하지 않습니다. 코드의이유가 "리소스 일시적으로 사용할 수 없습니다"
와 관계있는 부분 :
int numsems = concurrent_instrs.size();
std::cout << "Num sems: " << numsems << "\n";
// create semaphores
sem_t* sems = new sem_t[numsems];
for (int i = 0; i < numsems; i++)
{
if (sem_init(&sems[i], 1, 0) < 0)
{
perror("sem initialization failed");
exit(1);
}
}
int child_num = 0;
// perform all calculations in block concurrently
for(unsigned int i = 0; i < concurrent_instrs.size() && !isChild; i++)
{
int pid = fork();
if (pid == -1)
{
perror("Error forking:");
exit(1);
}
if (pid == 0)
{
isChild = true;
instr = concurrent_instrs[i];
}
else
{
child_num++;
}
}
if (isChild)
{
std::cout << "Child process " << child_num << " calculating: " << instr << "\n";
perform_calculation(instr, input_vars, internal_vars, shm_input, shm_internal);
std::cout << "Child process " << child_num << " finished calculating\n";
if (sem_post(&sems[child_num]) < 0)
{
perror("Child signal failed");
}
std::cout << "Child "<< child_num << " signalled\n";
// detach from shared memory
if (shmdt(shm_input) < 0)
{
perror("child shm_input detach failed");
}
if (shmdt(shm_internal) < 0)
{
perror("child shm_internal detach failed");
}
exit(0);
}
else
{
// parent waits for all children to finish
for (int i = 0; i < numsems; i++)
{
std::cout << "Waiting on subprocess " << i << " of " << numsems << "\n";
if (sem_trywait(&sems[i]) < 0)
perror("Parent wait failed");
else
std::cout << "Parent wait " << i << " working\n";
}
std::cout << "Finished waiting\n";
// destroy semaphores
for (int i = 0; i < numsems; i++)
{
if(sem_destroy(&sems[i]) < 0)
{
perror("Sem destroy failed");
exit(2);
}
else
{
std::cout << "Sem " << i << " destroyed\n";
}
}
delete[] sems;
}
내가 잘못 뭔가를 설정, 아니면 그냥이 상황에서 세마포어를 사용하는 방법에 대해 오해하고 있는가?
편집 추가 : sem_wait()는 자식 프로세스가 대기 전에 sem_post()를 호출하는지 여부에 관계없이 오류를 발견합니다.
어쩌면 나는 뭔가를 놓치고 있지만, 언뜻 보면 sem_wait()가 sem_post() 이후에 호출 될 것 같지 않으므로 기다릴 것이 없다. 어쩌면 나는 너무 빨리 코드를 읽었지만 여기에 내가 읽고있는 바가있다. 첫 번째 루프가'pid == 0 '조건을 만나지 않고 완전히 끝나면'isChild'는 여전히 false이므로'else' if (isChild)'대문자와 소문자를 구별합니다. 그러나 게시물이'if (isChild)'블록에 있기 때문에 게시되지 않고 즉시 대기합니다. – Scorch
@ imp903 pid는'fork()'에 의해 반환되며, 값은 부모에게 반환 된 포크에 의해 생성 된 자식의 프로세스 id이거나, 자식에게 반환 된 0입니다. 따라서'if (isChild)'블록 안의 모든 것은 자식 프로세스에 의해 실행되고, 'else' 블록은 부모에 의해 실행됩니다. print 문이 모두 실행되므로 제대로 작동합니다. – rangermattos