shmget 中没有这样的文件或目录错误

Posted

技术标签:

【中文标题】shmget 中没有这样的文件或目录错误【英文标题】:No such file or directory error in shmget 【发布时间】:2016-12-20 03:57:56 【问题描述】:

我在 Ubuntu 上用 C 语言实现了共享内存概念。我创建了两个文件 server.c 和 client.c ,首先我编译了 server.c 然后编译了 client.c 并运行它。但它显示了一个错误。 “没有相应的文件和目录” 此错误出现在 client.c 文件中,因为未找到请求的共享内存段。请帮助我如何解决这个问题。

这是我的代码

服务器.c

  #include<sys/types.h>
  #include<sys/shm.h>
  #include<sys/ipc.h>
  #include<string.h>
  #include<stdlib.h>
  #include<stdio.h>
  #include<errno.h>

  #define SHMSIZE 100

 int main()
 

 int shmid;
 key_t key;
 char *shm, *s;

 key=9876;
 shmid=shmget(key,SHMSIZE,IPC_CREAT|0666);
 if(shmid<0)
 
 printf("%s",strerror(errno));
 perror("Error in Shared Memory get statement");
 exit(1);
 

 shm=shmat(shmid,NULL,0);
 if(shm== (char *) -1)
 
 perror("Error in Shared Memory attachment");
 exit(1);
 

 memcpy(shm,"Hello World",11);
 s=shm;
 s+=11;

 while(*shm!='*')
 
 sleep(1);
 

 return 0;
 

client.c

#include<sys/types.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>

#define SHMSIZE 100

int main()


 int shmid;
 key_t key;
 char *shm, *s;

 key=9876;
 shmid=shmget(key,SHMSIZE,0666);
 if(shmid<0)
 
 printf("%s",strerror(errno));
 perror("Error in Shared Memory get statement");
 exit(1);
 

 shm=shmat(shmid,NULL,0);
 if(shm== (char *) -1)
 
 printf("%s",strerror(errno));
 perror("Error in Shared Memory attachment");
 exit(1);
 

 for(s=shm; *s!=0;s++)
 
 printf("%c",*s);
 
 printf("\n");
 *shm='*';
 return 0;
 

【问题讨论】:

在运行客户端之前是否运行了服务器?让服务器继续运行?我试过了,代码对我来说很好。 是的。我先运行了编译的服务器,然后编译了客户端,然后给出了运行命令。我的代码第一次运行,但现在它给出了这个错误 事实上 shmget() 失败并显示“没有这样的文件或目录”仅意味着它没有找到具有该键的段(现在迂腐:不是 id - 我们通常指的是 id到 shmget() 返回的值,随后使用) - 你检查过 shmid 是否相同?您的代码在我的系统上运行良好。 【参考方案1】:

shmget() 因“没有这样的文件或目录”而失败的事实仅意味着它没有找到具有该键的段(现在是迂腐的:不是 id - 我们通常使用 id 来引用返回的值shmget(),随后使用)-您检查过 shmid 是否相同?您的代码在我的系统上运行良好。

刚刚在它周围添加了一个 main() 。希望对你有帮助。

 key=9876;
 shmid=shmget(key,SHMSIZE,0666);
 if(shmid<0)
 
        printf("%s",strerror(errno));
        perror("Error in Shared Memory get statement");
        shmid = shmget(key, SHMSIZE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | IPC_CREAT);
        if (shmid == -1)  
                printf("%s",strerror(errno));
                perror("Error in Shared Memory get statement");
                exit(1);
        
 
printf("Shmget() successful %d\n",shmid);

【讨论】:

【参考方案2】:

我一直在调试 Frankenstein Linux 服务器,同时我从 php-7.4.22 opcache 复制了一些代码以具有相同的行为。

在我的情况下,此代码将 4 个 32MiB 的段分配到总共 128MiB。

/*
   +----------------------------------------------------------------------+
   | Zend OPcache                                                         |
   +----------------------------------------------------------------------+
   | Copyright (c) The PHP Group                                          |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@php.net>                                 |
   |          Zeev Suraski <zeev@php.net>                                 |
   |          Stanislav Malyshev <stas@zend.com>                          |
   |          Dmitry Stogov <dmitry@php.net>                              |
   +----------------------------------------------------------------------+
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#ifndef MIN
#define MIN(x, y) ((x) > (y) ? (y) : (x))
#endif

#define REQUEST_SIZE 128 * 1024 * 1024;

#define SEG_ALLOC_SIZE_MAX 32 * 1024 * 1024
#define SEG_ALLOC_SIZE_MIN 2 * 1024 * 1024

typedef struct

    size_t size;
    size_t pos; /* position for simple stack allocator */
    void *p;
 zend_shared_segment;

typedef struct

    zend_shared_segment common;
    int shm_id;
 zend_shared_segment_shm;

int main()

    key_t key = 9876;
    size_t requested_size = REQUEST_SIZE;

    int i;
    size_t allocate_size = 0, remaining_bytes = requested_size, seg_allocate_size;
    int first_segment_id = -1;
    key_t first_segment_key = -1;
    int shmget_flags;
    struct shmid_ds sds;
    zend_shared_segment_shm *shared_segments;
    zend_shared_segment_shm *shared_segments_p;
    int shared_segments_count = 0;

    printf("request_size: %d\n", requested_size);

    seg_allocate_size = SEG_ALLOC_SIZE_MAX;
    /* determine segment size we _really_ need:
     * no more than to include requested_size
     */
    while (requested_size * 2 <= seg_allocate_size && seg_allocate_size > SEG_ALLOC_SIZE_MIN)
    
        seg_allocate_size >>= 1;
    

    shmget_flags = IPC_CREAT | SHM_R | SHM_W | IPC_EXCL;

    /* try allocating this much, if not - try shrinking */
    while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN)
    
        allocate_size = MIN(requested_size, seg_allocate_size);
        first_segment_id = shmget(first_segment_key, allocate_size, shmget_flags);
        if (first_segment_id != -1)
        
            break;
        
        seg_allocate_size >>= 1; /* shrink the allocated block */
    

    printf("seg_allocate_size: %d\n", seg_allocate_size);

    if (first_segment_id == -1)
    
        perror("Failed to allocate first segment");
        return 1;
    

    shared_segments_count = ((requested_size - 1) / seg_allocate_size) + 1;
    printf("shared_segments_count: %d\n", shared_segments_count);

    shared_segments_p = calloc(shared_segments_count, sizeof(zend_shared_segment_shm) + sizeof(void *) * (shared_segments_count));
    if (!shared_segments_p)
    
        perror("Failure in calloc");
        return 1;
    
    shared_segments = (zend_shared_segment_shm *)((char *)(shared_segments_p) + sizeof(void *) * (shared_segments_count));

    remaining_bytes = requested_size;
    for (i = 0; i < shared_segments_count; i++)
    
        allocate_size = MIN(remaining_bytes, seg_allocate_size);
        if (i != 0)
        
            shared_segments[i].shm_id = shmget(IPC_PRIVATE, allocate_size, shmget_flags);
        
        else
        
            shared_segments[i].shm_id = first_segment_id;
        

        if (shared_segments[i].shm_id == -1)
        
            perror("Failed to allocate additional segments");
            return 1;
        

        shared_segments[i].common.p = shmat(shared_segments[i].shm_id, NULL, 0);
        if (shared_segments[i].common.p == (void *)-1)
        
            perror("Failed to shmat");
            shmctl(shared_segments[i].shm_id, IPC_RMID, &sds);
            return 1;
        
        shmctl(shared_segments[i].shm_id, IPC_RMID, &sds);

        shared_segments[i].common.pos = 0;
        shared_segments[i].common.size = allocate_size;
        remaining_bytes -= allocate_size;
    

    printf("Shmget() successful %d\n", first_segment_id);
    return 0;

运行它:gcc -o shm shm.c; sudo ./shm

【讨论】:

以上是关于shmget 中没有这样的文件或目录错误的主要内容,如果未能解决你的问题,请参考以下文章

运行 Solidity 合约导致“ENOENT:没有这样的文件或目录”错误

nohup 错误没有这样的文件或目录

在 for 循环中收到“没有这样的文件或目录”错误 - 最初识别文件

FileInputStream 错误没有这样的文件或目录

错误 C1083:无法打开包含文件:'crtdbg.h':没有这样的文件或目录

错误:QNetworkReply:没有这样的文件或目录