私は、親プロセスが(子プロセスごとに1つの)名前のないセマフォの配列を使用して、複数の子プロセスがシグナルを送るのを待っています。 sem_wait()は、sem_wait()を使用すると、親プロセスが無期限に待機し、sem_trywait()は「リソースが一時的に使用できません」というエラーを返し、子プロセスがシグナルを出すことなく続行します。 sem_init()もsem_post()もエラーを返しません。コードの理由が「リソースは一時的に利用できません」
Relevent部分:
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()は、子プロセスがwaitの前または後にsem_post()を呼び出すかどうかに関係なくエラーを検出します。
多分私は何かが不足しているかもしれませんが、一見するとsem_wait()がsem_post()の後に呼び出されるようには見えないので、待つことはありません。たぶん私はコードをあまりにも速く読んでいますが、ここで私が読んでいることがあります:最初のループが 'pid == 0'条件に遭遇することなく完全に通り、' isChild'はまだfalseであるので、 'else' if(isChild) 'ケースをバイパスします。しかし、ポストは 'if(isChild)'ブロックにあるので、ポストされずにすぐに待機します。 – Scorch
@ imp903 pidは 'fork()'によって返され、値は親に返されたforkによって作成された子のプロセスID、または子に返された0です。 'if(isChild)'ブロック内のすべては子プロセスによって実行され、 'else'ブロックは親プロセスによって実行されます。 printステートメントはすべて実行されるため、正常に動作しています。 – rangermattos