首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sem_wait在我的程序中被忽略

sem_wait在我的程序中被忽略
EN

Stack Overflow用户
提问于 2014-01-09 02:13:24
回答 1查看 1K关注 0票数 1

我在linux中编写了一个关于共享内存的简单项目。有两个程序共享内存,一个是写信给它,另一个是从中读取它们。我决定使用信号灯,以确保在阅读之前不会产生新的字母。

问题是我的写入进程忽略了sem_wait(读取),当它的值为0时,它应该等待。它甚至在读者开始之前就完成了它的工作。我在./writer & ./reader上查过了。

我附上密码。这里有一些未使用的元素,因为它还不是最终版本。然而,问题已经解决了。

代码语言:javascript
复制
/* 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;
}

而读者,

代码语言:javascript
复制
/* 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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-09 02:38:13

sharedMemory + 3sem_t类型没有正确对齐。由于您不知道sem_t的对齐需求,所以需要确保您的sem_t对象从共享内存段中的偏移量(即sizeof(sem_t)的倍数)开始(这是因为任何对象的对齐需求都将其大小平分)。

请注意,您应该检查sem_waitsem_post的返回值。然后,您可以检查errno是否失败,这将为您提供关于它们失败原因的信息(但是,在您的情况下,我怀疑errno值可能没有多大帮助)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21010454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档