【问题标题】:No such file or directory error in shmgetshmget 中没有这样的文件或目录错误
【发布时间】: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 是否相同?您的代码在我的系统上运行良好。

标签: c ubuntu ipc shared-memory


【解决方案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

    【讨论】:

      猜你喜欢
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-08
      • 2013-11-04
      • 2012-02-18
      • 2012-10-21
      相关资源
      最近更新 更多