共享 memory/mmap
shared memory/mmap
我对 C 和 Unix 还很陌生,所以这可能是个愚蠢的问题。昨天我一直在尝试制作两个通过共享内存相互通信的程序。一个是接收者,一个是发送者。
下面的接收器设置了共享内存和2个信号量(一个用于读取另一个用于写入)并在循环中等待接收内容,如果接收到的字符串为空则终止循环。
两个程序都使用 3 个标志:
-m (shared_memory_name)
-w (writing_semaphore_name)
-r (reading_semaphore_name)
int main(int argc, char** argv)
{
//sem_in,sem_out,shared_mem_fd,getopt stuff
//getopt()...
while(1)
{
//waiting for sender to change the sem
if(sem_wait(sem_out)==-1){ //waits for the sender to change the semaphore
//error
}
char* data = mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,0);
if(data == MAP_FAILED){
//error
}
if(strlen(data) == 0){
//terminate program
}
if(sem_post(sem_in)==-1){
//error
}
}
//close sems and shared memory
return 0
}
下面的发送者假设打开共享内存FD并放入一些东西,那是我从argv[optind]得到的附加参数,通常是一个字符串。
int main(int argc, char** argv){
//sems,getopt variables,filedescriptor
char* data;
//getopt()
data = argv[optind];
if(sem_in == SEM_FAILED || sem_out == SEM_FAILED || SHM_FD == -1){
//error
}
//printf("waiting\n");
if(sem_wait(sem_in)==-1){
//error
}
data = mmap(NULL,strlen(data),PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,0);
if(data==MAP_FAILED){
//error
}
if(sem_post(sem_out)==-1){
//error
}
close(shared memory);
return 0;
}
我是这样使用程序的:
./receiver -m /mem1 -w /s1 -r /s2 (creates the memory and sems and waits)
waiting
./sender -m /mem1 -w /s1 -r /s2 hello (send a string)
./receiver -m /mem1 -w /s1 -r /s2
waiting
empty
尽管我发送了一些东西,但接收者说字符串是空的。信号量改了,所以就这样了。
就像我说的,我在这方面几乎是个菜鸟,所以我很容易犯愚蠢的错误,我希望我能很好地解释我的问题,我们将不胜感激。
P.S。变量名是我的语言,所以如果我忘记翻译一些,请原谅我,我也做了很多实验,所以以前版本的一些包含仍然存在...
问题是您没有在共享内存中存储任何内容。您在代码中有以下两行...
data = argv[optind];
data = (char*)mmap(NULL,strlen(data),PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,(off_t)0);
第二个覆盖 data
的内容,然后您不会将任何内容复制到它指向的内存中。
因为它并没有真正做任何有用的事情,你应该删除第一行。要填充共享内存,请在打开它后 添加此行 。
memcpy(data,argv[optind],strlen(argv[optind])+1);
并且由于您不再将 data
指向参数,因此您也需要更改共享内存的打开方式。
data = (char*)mmap(NULL,strlen(argv[optind])+1,PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,(off_t)0);
您会注意到我在字符串的长度上加了 1 - 这是为了确保有足够的 space 来包含 NUL 终止字符。
我对 C 和 Unix 还很陌生,所以这可能是个愚蠢的问题。昨天我一直在尝试制作两个通过共享内存相互通信的程序。一个是接收者,一个是发送者。
下面的接收器设置了共享内存和2个信号量(一个用于读取另一个用于写入)并在循环中等待接收内容,如果接收到的字符串为空则终止循环。 两个程序都使用 3 个标志: -m (shared_memory_name) -w (writing_semaphore_name) -r (reading_semaphore_name)
int main(int argc, char** argv)
{
//sem_in,sem_out,shared_mem_fd,getopt stuff
//getopt()...
while(1)
{
//waiting for sender to change the sem
if(sem_wait(sem_out)==-1){ //waits for the sender to change the semaphore
//error
}
char* data = mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,0);
if(data == MAP_FAILED){
//error
}
if(strlen(data) == 0){
//terminate program
}
if(sem_post(sem_in)==-1){
//error
}
}
//close sems and shared memory
return 0
}
下面的发送者假设打开共享内存FD并放入一些东西,那是我从argv[optind]得到的附加参数,通常是一个字符串。
int main(int argc, char** argv){
//sems,getopt variables,filedescriptor
char* data;
//getopt()
data = argv[optind];
if(sem_in == SEM_FAILED || sem_out == SEM_FAILED || SHM_FD == -1){
//error
}
//printf("waiting\n");
if(sem_wait(sem_in)==-1){
//error
}
data = mmap(NULL,strlen(data),PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,0);
if(data==MAP_FAILED){
//error
}
if(sem_post(sem_out)==-1){
//error
}
close(shared memory);
return 0;
}
我是这样使用程序的:
./receiver -m /mem1 -w /s1 -r /s2 (creates the memory and sems and waits)
waiting
./sender -m /mem1 -w /s1 -r /s2 hello (send a string)
./receiver -m /mem1 -w /s1 -r /s2
waiting
empty
尽管我发送了一些东西,但接收者说字符串是空的。信号量改了,所以就这样了。
就像我说的,我在这方面几乎是个菜鸟,所以我很容易犯愚蠢的错误,我希望我能很好地解释我的问题,我们将不胜感激。
P.S。变量名是我的语言,所以如果我忘记翻译一些,请原谅我,我也做了很多实验,所以以前版本的一些包含仍然存在...
问题是您没有在共享内存中存储任何内容。您在代码中有以下两行...
data = argv[optind];
data = (char*)mmap(NULL,strlen(data),PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,(off_t)0);
第二个覆盖 data
的内容,然后您不会将任何内容复制到它指向的内存中。
因为它并没有真正做任何有用的事情,你应该删除第一行。要填充共享内存,请在打开它后 添加此行 。
memcpy(data,argv[optind],strlen(argv[optind])+1);
并且由于您不再将 data
指向参数,因此您也需要更改共享内存的打开方式。
data = (char*)mmap(NULL,strlen(argv[optind])+1,PROT_READ|PROT_WRITE,MAP_SHARED,SHM_FD,(off_t)0);
您会注意到我在字符串的长度上加了 1 - 这是为了确保有足够的 space 来包含 NUL 终止字符。