【发布时间】:2014-01-09 02:13:24
【问题描述】:
我在 linux 中写了一个关于共享内存的简单项目。两个程序共享内存,一个是给它写信,第二个是从中读取它们。我决定使用信号量来确保在读取之前不会产生新的字母。
问题是我的 writer 进程在 sem_wait(reading) 的值为 0 时忽略了它,它应该等待。它甚至在读者开始之前就完成了它的工作。我通过./writer & ./reader 运行它。
我附上代码。这里有一些未使用的元素,因为它还不是最终版本。但是问题已经出现了。
/* writer.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
int main( int argc, char *argv[] )
{
key_t shmkey = 0xF00;
int bytes = sizeof(char)*3 + sizeof(sem_t) * 3;
int shmid;
char* sharedMemory;
sem_t *writing, *reading, *working;
if ( (shmid = shmget( shmkey, bytes, IPC_CREAT | IPC_EXCL | 0666 )) < 0 )
{
shmdt( (void*) sharedMemory );
shmctl( shmid, IPC_RMID, NULL );
return 1;
}
if ( (sharedMemory = (char*) shmat( shmid, NULL, 0 )) == (char*) -1 )
{
shmdt( (void*) sharedMemory );
shmctl( shmid, IPC_RMID, NULL );
return 1;
}
writing = (sem_t*)(sharedMemory + 3);
reading = writing + 1;
working = reading + 1;
sem_init( writing, 0, 0 );
sem_init( reading, 0, 0 );
sharedMemory[2] = 'w'; // writer is running
char c;
for( c = 'a'; c <= 'z'; ++c )
{
*sharedMemory = c;
sem_post( writing );
sem_wait( reading );
}
sharedMemory[2] = 'q';
while ( sharedMemory[2] != 'w' );
sharedMemory[2] = 'q';
shmdt( (void*) sharedMemory );
shmctl( shmid, IPC_RMID, NULL );
return 0;
}
还有读者,
/* reader.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
int main( int argc, char *argv[] )
{
key_t shmkey = 0xF00;
int bytes = sizeof(char)*3 + sizeof(sem_t) * 3;
int shmid;
char* sharedMemory;
sem_t *writing, *reading, *working;
sleep(1); // wait until writer allocates fresh memory
if ( (shmid = shmget( shmkey, bytes, 0666 )) < 0 )
{
shmdt( (void*) sharedMemory );
return 1;
}
if ( (sharedMemory = (char*) shmat( shmid, NULL, 0 )) == (char*) -1 )
{
shmdt( (void*) sharedMemory );
return 1;
}
if ( sharedMemory[2] != 'w' ) // is writer running?
{
shmdt( (void*) sharedMemory );
return 1;
}
writing = (sem_t*)(sharedMemory + 3);
reading = writing + 1;
working = reading + 1;
//sleep(5); //@REMOVE
char c;
do
{
sem_wait( writing );
c = *sharedMemory;
sem_post( reading );
printf( "%c\n", c );
} while ( sharedMemory[2] == 'w' );
sharedMemory[2] = 'w';
shmdt( (void*) sharedMemory );
return 0;
}
【问题讨论】:
-
文档说
sem_init()的第二个参数应该是非零的,以便在进程之间共享信号量 - 您似乎正在调用未定义的行为。如果你改变它会发生什么? -
@Notlikethat 它没有帮助
-
您还应该检查返回值 - 失败时读取
errno会告诉您出了什么问题。 -
@woolstar 我不知道。我以前使用过信号量,但没有那个过程,虽然没有共享内存。您能否给我一个提示该命令的外观,即我应该设置哪些标志以及代码末尾的 destroy() 是否足以释放它的内存?
-
对不起,您使用的样式称为未命名信号量,我很熟悉,但基本上是有效的。
标签: c linux semaphore shared-memory