我正在尝试执行一些基本的并行处理,以便使用POSIX共享内存段和未命名信号量对整数进行奇偶排序。如果我在信号量锁定和解锁之后直接离开perror()调用,代码将完美地对整数数组进行排序。
int semaphoreCheck = sem_init(&(sharedData->swapSem), 1, 1);
if (semaphoreCheck == -1)
{
perror( "failed to initialize semaphore" );
exit(EXIT_FAILURE);
}
pid_t fork1;
fork1 = fork();
if (fork1 == 0)
{
// original.child
pid_t fork2;
fork2 = fork();
if (fork2 == 0)
{
// child.child
// do a portion of the sort here
while(sharedData->evenSwap || sharedData->oddSwap)
{
// obtain lock on the shared vector
// int commandCheck = shmctl(sharedID, SHM_LOCK, NULL);
int commandCheck = sem_wait(&(sharedData->swapSem));
perror("semaphore lock");
// if lock was obtained
if (commandCheck == 0)
{
sharedData->evenSwap = false;
for( int index = 1; index < arraySize - 1; index +=2)
{
if( sharedData->vecData[index] > sharedData->vecData[index + 1] )
{
int temp;
temp = sharedData->vecData[index];
sharedData->vecData[index] = sharedData->vecData[index+1];
sharedData->vecData[index+1] = temp;
sharedData->evenSwap = true;
}
}
// release lock on the shared vector
commandCheck = sem_post(&(sharedData->swapSem));
perror("semaphore unlock");
if (commandCheck == -1)
{
perror("failed to unlock shared semaphore");
}
}
else perror("failed to lock shared semaphore");
}
_exit(0);
}
else if (fork2 > 0)
{
// child.parent
// do a portion of the sort here
while(sharedData->evenSwap || sharedData->oddSwap)
{
// obtain lock on the shared vector
int commandCheck = sem_wait(&(sharedData->swapSem));
perror("semaphore lock");
// if lock was obtained
if (commandCheck == 0)
{
sharedData->oddSwap = false;
for( int index = 0; index < arraySize - 1; index +=2)
{
if( sharedData->vecData[index] > sharedData->vecData[index + 1] )
{
int temp;
temp = sharedData->vecData[index];
sharedData->vecData[index] = sharedData->vecData[index+1];
sharedData->vecData[index+1] = temp;
sharedData->oddSwap = true;
}
}
// release lock on the shared vector
commandCheck = sem_post(&(sharedData->swapSem));
perror("semaphore unlock");
if (commandCheck == -1)
{
perror("failed to unlock shared semaphore");
}
}
else perror("failed to lock shared semaphore");
}
_exit(0);
}
else
{
// child.error
// forking error.
perror("failed to fork in child");
exit(EXIT_FAILURE);
}
}
else if( fork1 > 0)
{
// original.parent
// wait for the child process to finish.
waitpid(fork1, NULL, 0);
}
else
{
// forking error
perror("failed to fork");
exit(EXIT_FAILURE);
}我只能猜测这与当等待无法完成时信号量如何阻塞进程有关,但我不明白perror()调用如何修复它。
发布于 2011-06-21 09:46:15
我认为您的问题可能与您在获得信号量后检查条件是否仍然适用的方式有关,或者检查条件本身是错误的。
您必须:
while(sharedData->evenSwap || sharedData->oddSwap)
{
// obtain lock on the shared vector
int commandCheck = sem_wait(&(sharedData->swapSem));
perror("semaphore lock");
// if lock was obtained
if (commandCheck == 0)
{
sharedData->oddSwap = false;在获得信号量之后,您可能应该验证sharedData->evenSwap或sharedData->oddSwap是否仍然为真,如果不是,则放弃信号量。这是一个标准的习惯用法;你检查、锁定和重新检查,因为在最初的检查和获得锁的时间之间,状态可能已经改变。
在这个假设下,perror()调用改变了进程的时间,允许条件保持不变的时间比不存在perror()调用的时间更长。
https://stackoverflow.com/questions/6419296
复制相似问题