简体   繁体   English

sem_wait在我的程序中被忽略

[英]sem_wait is ignored in my program

I write a simple project on shared memory in linux. 我在linux上的共享内存上编写了一个简单的项目。 Two programs share memory, one is writing letters to it and second is reading them from it. 两个程序共享内存,一个程序向其中写入字母,第二个程序从中读取它们。 I decided to use semaphores in order to ensure that no new letter is produced until it is read. 我决定使用信号量,以确保在读取之前不会产生新的字母。

The problem is that my writer process is ignoring sem_wait( reading ) when its value is 0 and it should wait. 问题是我的编写器进程在其值为0且应等待时忽略了sem_wait(reading)。 It finishes its job before the reader even starts. 它甚至在读者开始之前就完成了工作。 I run it through ./writer & ./reader . 我通过./writer & ./reader运行它。

I enclose the code. 我附上代码。 There are a few unused elements here because it is not the final version yet. 这里有一些未使用的元素,因为它不是最终版本。 However problem already arised. 但是问题已经出现。

/* 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;
}

And the reader, 还有读者

/* 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;
}

sharedMemory + 3 is not properly aligned for type sem_t . sharedMemory + 3对于sem_t类型未正确对齐。 Since you don't know the alignment requirement for sem_t , you need to make sure that your sem_t objects start at an offset in the shared memory segment that is a multiple of sizeof(sem_t) (this works because the alignment requirement of any object evenly divides its size). 由于您不知道sem_t的对齐要求,因此需要确保sem_t对象从共享内存段中的偏移量开始,该偏移量是sizeof(sem_t)的倍数(这很有效,因为任何对象的对齐需求均等划分大小)。

Note that you should be checking the return values of sem_wait and sem_post . 请注意,您应该检查sem_waitsem_post的返回值。 Then you could inspect errno if they fail and that would give you information on why they're failing (however in your case I suspect the errno value may have been less than helpful). 然后,您可以检查errno是否失败,这将为您提供有关它们失败原因的信息(但是,在您的情况下,我怀疑errno值可能没有帮助)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM