C - POSIX:共享内存

Posted

技术标签:

【中文标题】C - POSIX:共享内存【英文标题】:C - POSIX: Shared Memory 【发布时间】:2013-12-27 19:59:15 【问题描述】:

以下代码有问题:

struct 
    int a, b;
    sem_t client;
    sem_t server;
 *shm_acc;

void server() 
    while(1) 
        sem_wait(&shm_acc->server);

        if(shm_acc->a == -1 && shm_acc->b == -1)
           return;

        printf("The product of the two entered numbers is %d\n", shm_acc->a * shm_acc->b)
        sem_post(&shm_acc->client);
    


void client() 
    while(1) 
        printf("Please enter two unsigned integer with whitespace in between. For exit enter -1 -1.\n");
        if(2 != scanf("%d %d\n", &shm_acc->a, &shm_acc->b) 
            perror("An error occured. Please try again\n");

            while(getchar() != '\n');

            continue;
        

         sem_post(&shm_acc->server);

         if(shm_acc->a == -1 && shm_acc->b == -1)
            return;

         sem_wait(&shm_acc->client);

     

     exit(EXIT_SUCCES);


int main() 
    setbuf(stdout, NULL);

    int shm = 0;
    shm = shmget(IPC_PRIVATE, SHAREDMEM_SIZE, S_IRUSR | S_IWUSR);
    if(shm == -1)
        perror("Failed to create shared memory.\n");

    shm_acc = shmat(shm, NULL, 0);

    sem_init(&shm_acc->client, 1, 0);
    sem_init(&shm_acc->server, 1, 0);

    pid_t pid = fork();

    if(pid == 0) 

        client();
        shmdt(shm_acc);
     else if(pid >0) 

        server();
        waitpid(pid, NULL, 0);
        sem_destroy(&shm_acc->server);
        sem_destroy(&shm_acc->client);
     else if(pid == -1) 

        perror("fork");
        sem_destroy(&shm_acc->server);
        sem_destroy(&shm_acc->client);
    

    return 0;

在上面的代码中,客户端和服务器使用 POSIX 共享内存相互通信。父进程代表服务器,子进程代表客户端。另外,我正在使用 POSIX 信号量。这 服务器必须等到客户端输入两个值才能处理输入, 客户端必须等到服务器处理完输入并打印输出后才能提示输入新的输入值

问题是,代码没有按应有的方式运行。

应该是这样的:

Please enter two unsigned integer with whitespace in between. For exit enter -1 -1.
2 2
The product of the two entered values is 4.
Please enter two unsigned integer with whitespace in between. For exit enter -1 -1.
3 3
The product of the two entered values is 9.
Please enter two unsigned integer with whitespace in between. For exit enter -1 -1.
-1 -1
//exit

但它的作用是:

Please enter two unsigned integer with whitespace in between. For exit enter -1 -1.
2 2 // after entering it doesn't calculate the input
2 3 // after entering again it calculates 2x2
The product of the two entered values is 4.
Please enter two unsigned integer with whitespace in between. For exit enter -1 -1.
3 3
The product of the two entered values is 6. // This is the result of input 2x3, see above
Please enter two unsigned integer with whitespace in between. For exit enter -1 -1.
-1 -1
The product of the two entered values is 9
2 4
// Now it terminates.

我不知道出了什么问题。有谁知道,为什么代码会这样?

【问题讨论】:

【参考方案1】:

scanf 格式字符串的末尾留下\n 几乎总是会出现问题(fscanf 的问题较少,因为它不是交互式的),因为格式字符串中的任何空白字符都确实存在用于“0 个或多个(可能无限多个)空白字符”——它们可以是任何空白字符(空格、制表符或回车符)。

因此,当您将\n(或<space>\t)放在格式字符串的末尾时,scanf 不会停止并返回输入,直到它看到非空白字符(或遇到某种匹配错误)。从您的角度来看,它似乎没有打印提示或处理输入;那是因为它不是——它仍然在同一个地方。如果您只在该行中输入了一个数字,同样的事情也会发生——程序会暂停,因为scanf 仍在等待您输入第二个数字(和以前一样,您输入的回车键“适合" 格式中的空格,所以还没有匹配错误)。

由于%d(以及除了%c%[ 之外的几乎所有格式说明符)忽略前导空格无论如何,您经常会发现没有必要明确包含它们.

【讨论】:

以上是关于C - POSIX:共享内存的主要内容,如果未能解决你的问题,请参考以下文章

C - POSIX:共享内存

如何在 c 中使用 posix 命名信号量和 Linux 上两个进程之间的共享内存?

共享内存和 POSIX 信号量

Posix 共享内存与映射文件

Posix共享内存

POSIX 共享内存 - 有多少个内存副本