2016-11-11 5 views
1

이유와 함께 기다리는 세마포는 부모 프로세스가 (자식 프로세스 당 하나씩) 명명되지 않은 세마포 배열을 사용하여 계속하기 전에 여러 자식 프로세스가 대기하는 것을 기다리고 있습니다. 그러나 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()를 호출하는지 여부에 관계없이 오류를 발견합니다.

+0

어쩌면 나는 뭔가를 놓치고 있지만, 언뜻 보면 sem_wait()가 sem_post() 이후에 호출 될 것 같지 않으므로 기다릴 것이 없다. 어쩌면 나는 너무 빨리 코드를 읽었지만 여기에 내가 읽고있는 바가있다. 첫 번째 루프가'pid == 0 '조건을 만나지 않고 완전히 끝나면'isChild'는 여전히 false이므로'else' if (isChild)'대문자와 소문자를 구별합니다. 그러나 게시물이'if (isChild)'블록에 있기 때문에 게시되지 않고 즉시 대기합니다. – Scorch

+0

@ imp903 pid는'fork()'에 의해 반환되며, 값은 부모에게 반환 된 포크에 의해 생성 된 자식의 프로세스 id이거나, 자식에게 반환 된 0입니다. 따라서'if (isChild)'블록 안의 모든 것은 자식 프로세스에 의해 실행되고, 'else' 블록은 부모에 의해 실행됩니다. print 문이 모두 실행되므로 제대로 작동합니다. – rangermattos

답변

0

sem_t* sems = new sem_t[numsems];으로 할당 된 세마포어는 공유 메모리에 없습니다. 따라서 각 프로세스에는 자체 사본이 있으며 하위에 게시해도 상위에 영향을주지 않습니다.

부모의 복사본이 잠긴 상태로 유지됩니다. sem_trywaitEAGAIN으로 실패합니다. 이는 resource temporarily unavailable 설명으로 바뀝니다.

+0

나는 이것을 깨닫지 못했다고 생각합니다. 고마워요. 내가 본 튜토리얼에서는 공유 메모리에 세마포어를 저장해야했습니다. – rangermattos