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:没有这样的文件或目录”错误
在 for 循环中收到“没有这样的文件或目录”错误 - 最初识别文件