Linux共享内存,带有C :分段故障



我正在关注Linux编程接口书(第1004-1005页)。

我知道这本书使用C。但是我想在C 中实现相同的行为。也就是说:通过共享内存共享过程之间的结构。

#include <iostream>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
using namespace std;
struct my_pair {
  int a;
  int b;
};
int main()
{
  key_t key = ftok("aaaaa", 1);
  int shmid = shmget(key, sizeof(my_pair), IPC_CREAT);
  my_pair *numbers;
  numbers = shmat(shmid, NULL, 0);
  cout << numbers->a;
  return 0;
}

它给了我这个错误:

shteste.cpp:在函数'int main()'中:

shteste.cpp:18:错误:从'void*'到'my_pair*'

的转换无效

我知道C 更严格。如果我将SHMAT的返回归还为(my_pair *),它会编译,但在执行过程中给我分段故障。

使用c 的Linux/c共享内存设施是否可能(如何)?

我正在使用:G 4.4.7:G shteste.cpp -o shteste -std = C 0x

谢谢...

编辑:遵循所有SUMENTIONS,这是现在的代码:

int main()
{
 key_t key;
 if ((key = ftok("/home/alunos/scd/g11/aaaaa", 1)) == (key_t) -1) {
   perror("IPC error: ftok"); exit(1);
 }
 int shmid = shmget(key , sizeof(my_pair), IPC_CREAT | 0640);
 if (shmid == -1) {
     perror("Could not get shared memory");
     return EXIT_FAILURE;
 }
 my_pair *numbers;
 void* mem = (my_pair*) shmat(shmid, NULL, 0);
 if (mem == reinterpret_cast<void*>(-1)) {
     perror("Could not get shared memory location");
     return EXIT_FAILURE;
 } else {
     numbers = reinterpret_cast<my_pair*>(mem);
     cout << numbers->a;
 }
 return EXIT_SUCCESS;
}

aaaaa内容:notacat

[scd11@vm11〜] $ ./shteste

无法获得共享内存:拒绝权限

这可能是权限问题。您可以检查shmgetshmat的返回值,并使用perror打印这样的人类可读性错误消息。

#include <iostream>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
struct my_pair {
  int a;
  int b;
};
int main()
{
  key_t key = ftok("aaaaa", 1);
  int shmid = shmget(key, sizeof(my_pair), IPC_CREAT | 0777);
  if (shmid == -1) {
      perror("Could not get shared memory");
      return EXIT_FAILURE;
  }
  my_pair *numbers;
  void* mem = (my_pair*) shmat(shmid, NULL, 0);
  if (mem == reinterpret_cast<void*>(-1)) {
      perror("Could not get shared memory location");
      return EXIT_FAILURE;
  } else {
      numbers = reinterpret_cast<my_pair*>(mem);
      cout << numbers->a;
  }
  return EXIT_SUCCESS;
}

您简单地忘记设置权限:

int shmid = shmget(key, sizeof(my_pair), IPC_CREAT | 0777);

正如我在评论中已经提到的那样,可以通过strace看到失败命令的结果。

64 5327 shmget(0xffffffff, 8, IPC_CREAT|000) = 11534358
65 5327 shmat(11534358, NULL, 0) = -1 EACCES (Permission denied)"

如果您的文件" AAAAA"存在,则代码对我有用。

这是一个权限问题。

根据shmget()文档:

摘要

#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);

...

描述

...

  • shm_perm.mode 的低阶九位设置为 shmflg 的低阶九位。。

您没有设置任何权限位。您的呼叫中的 shmflag shmflag 的低排序均为零:

int shmid = shmget(key, sizeof(my_pair), IPC_CREAT);

您需要设置适当的权限,类似的内容:

int shmid = shmget(key, sizeof(my_pair), IPC_CREAT|0640);

您还可能必须使用ipcrm来删除当前的共享内存段,因为它将保持不正确的permss。即使更改代码,您的shmget()调用也将返回现有段的ID-由于丢失了权限,因此无法附加的段。

首先,使用ipcs -a列出共享内存段,然后使用ipcrm -m shmidipcrm -M shmkey使用不正确的权限删除段。

根据ftok人页:

The ftok() function uses the identity of the file named by the given
pathname (which must refer to an existing, accessible file).

使用现有文件,您的代码将起作用。

或者您可以使用:

key = IPC_PRIVATE

这对于此示例就足够了,但对真正的IPC不起作用。

相关内容

  • 没有找到相关文章