shmat(3) 函数 returns 0xffffffffffffffff 地址
shmat(3) function returns 0xffffffffffffffff address
我一直在努力使用 IPC 共享内存。我正在尝试通过 BSD TCP 套接字编写简单的服务器/客户端程序通信。服务器是多线程的,并为用户之间的多个并行国际象棋对决提供服务。每个线程只与一个用户相关联。要共享有关移动和决斗状态的数据,我想使用共享内存,因为服务器控制几乎所有内容。
我创建了决斗 class 并且每次决斗请求被接受时,服务器都会创建新的共享内存并将密钥传递给用户:
this->key_kernel = (this->key_kernel + 17) % 1000000;
int shmid = shmget(this->key_kernel, sizeof(Duel), 0666 | IPC_CREAT);
challenger->set_shmkey(this->key_kernel);
challenged->set_shmkey(this->key_kernel);
Duel *duel = (Duel *)shmat(shmid, (void *)0, 0);
duel->init_duel(challenger, challenged);
shmdt(duel);
当控制通信的线程注意到决斗开始时,它会做类似的事情:
shmid = shmget(current_user->get_shmkey(), sizeof(Duel), 0666 | IPC_CREAT);
duel = (Duel *)shmat(shmid, (void *)0, 0);
并且使用决斗的方式。它工作正常,但是......最多五场决斗。我注意到每次在 5 次决斗(即 5 次决斗接受)之后,无论完成还是进行中 - 程序都会失败(分段错误)
经过调查,我注意到应该由 shmat 附加到共享内存的决斗指针此时为 0xffffffffffffffff。我也注意到一些 errno 24.
即使是一些草率的修复,比如检查指针是否不是 0xffff,我也会很感激……但我真的不知道这是否可能。类似于:
int *a;
a = nullptr;
if (a == nullptr) {...}
对于 nullptr 这很容易,但我不知道如何将自定义(即决斗指针)转换为 char* 或其他东西来比较它。
来自男人:
shmat() returns the address at which the shared memory segment has been mapped into the calling process' address space when successful, shmdt() returns 0 on successful completion. Otherwise, a value of -1 is
returned, and the global variable errno is set to indicate the error.
您看到的 0xffffffffffffffff
指针 -1
表示错误。
向您的程序添加一个 if,它检查 shmat
和 shmget
的 return 值是否有错误。在 if 中,您可以使用 perror
函数打印一条错误消息,告诉您出了什么问题。
这是一般规则。您应该始终检查系统调用的 return 个值:
a = system_call_x();
if (a == (void*) -1) {
perror("system_call_x failed, exiting");
exit(1);
}
我一直在努力使用 IPC 共享内存。我正在尝试通过 BSD TCP 套接字编写简单的服务器/客户端程序通信。服务器是多线程的,并为用户之间的多个并行国际象棋对决提供服务。每个线程只与一个用户相关联。要共享有关移动和决斗状态的数据,我想使用共享内存,因为服务器控制几乎所有内容。
我创建了决斗 class 并且每次决斗请求被接受时,服务器都会创建新的共享内存并将密钥传递给用户:
this->key_kernel = (this->key_kernel + 17) % 1000000;
int shmid = shmget(this->key_kernel, sizeof(Duel), 0666 | IPC_CREAT);
challenger->set_shmkey(this->key_kernel);
challenged->set_shmkey(this->key_kernel);
Duel *duel = (Duel *)shmat(shmid, (void *)0, 0);
duel->init_duel(challenger, challenged);
shmdt(duel);
当控制通信的线程注意到决斗开始时,它会做类似的事情:
shmid = shmget(current_user->get_shmkey(), sizeof(Duel), 0666 | IPC_CREAT);
duel = (Duel *)shmat(shmid, (void *)0, 0);
并且使用决斗的方式。它工作正常,但是......最多五场决斗。我注意到每次在 5 次决斗(即 5 次决斗接受)之后,无论完成还是进行中 - 程序都会失败(分段错误)
经过调查,我注意到应该由 shmat 附加到共享内存的决斗指针此时为 0xffffffffffffffff。我也注意到一些 errno 24.
即使是一些草率的修复,比如检查指针是否不是 0xffff,我也会很感激……但我真的不知道这是否可能。类似于:
int *a;
a = nullptr;
if (a == nullptr) {...}
对于 nullptr 这很容易,但我不知道如何将自定义(即决斗指针)转换为 char* 或其他东西来比较它。
来自男人:
shmat() returns the address at which the shared memory segment has been mapped into the calling process' address space when successful, shmdt() returns 0 on successful completion. Otherwise, a value of -1 is returned, and the global variable errno is set to indicate the error.
您看到的 0xffffffffffffffff
指针 -1
表示错误。
向您的程序添加一个 if,它检查 shmat
和 shmget
的 return 值是否有错误。在 if 中,您可以使用 perror
函数打印一条错误消息,告诉您出了什么问题。
这是一般规则。您应该始终检查系统调用的 return 个值:
a = system_call_x();
if (a == (void*) -1) {
perror("system_call_x failed, exiting");
exit(1);
}