这里是同步的读取器和写入器。目标是通过共享内存在这两个进程之间传递数据。 编写器通过结构打开共享内存并写入一些数据。我收到Segmentation Fault(Core Dumped)错误消息。 该代码是在Ubuntu中通过以下命令编译的。
g++ Writer.c -o Writer -lrt
g++ Reader.c -o Reader -lrt
这两个流程由-
运行./Writer
./Reader
作家。c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main(void){
struct MemData{
char* FileName;
int LastByteLength;
int ReadPointer;
int WritePointer;
char Data[512000];//MEMORY BLOCK SIZE: 500 KB
};
int SD;
struct MemData *M;
int NumberOfBuffers=10;
int BufferSize=51200;//FILE BUFFER SIZE 50 KB
SD= shm_open("/program.shared", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
if(SD< 0){
printf("\nshm_open() error \n");
return EXIT_FAILURE;
}
fchmod(SD, S_IRWXU|S_IRWXG|S_IRWXO);
if(ftruncate(SD, sizeof(MemData))< 0){
printf ("ftruncate() error \n");
return EXIT_FAILURE;
}
//THE FOLLOWING TYPECASTING AVOIDS THE NEED TO ATTACH THROUGH shmat() in shm.h HEADER I GUESS.
M=(struct MemData*)mmap(NULL, sizeof(MemData), PROT_READ|PROT_WRITE, MAP_SHARED, SD, 0);
if(M== MAP_FAILED){
printf("mmap() error");
return EXIT_FAILURE;
}else{
M->FileName=(char*)"xaa";
M->LastByteLength=0;
M->ReadPointer=-1;
M->WritePointer=-1;
memset(M->Data, '\0', strlen(M->Data));
}
/*
FILE *FP= fopen(FileName, "rb");
if(FP!= NULL){
unsigned long int FilePosition;
fseek(FP, 0, SEEK_SET);
FilePosition=ftell(FP);
fclose(FP);
}
*/
close(SD);
return 0;
}
读者。c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main(void){
struct MemData{
char* FileName;
int LastByteLength;
int ReadPointer;
int WritePointer;
char Data[512000];//MEMORY BLOCK SIZE: 500 KB
};
int SD;
struct MemData *M;
int NumberOfBuffers=10;
int BufferSize=51200;//FILE BUFFER SIZE 50 KB
SD= shm_open("/program.shared", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
if(SD< 0){
printf("\nshm_open() error \n");
return EXIT_FAILURE;
}
fchmod(SD, S_IRWXU|S_IRWXG|S_IRWXO);
if(ftruncate(SD, sizeof(MemData))< 0){
printf ("ftruncate() error \n");
return EXIT_FAILURE;
}
//THE FOLLOWING TYPECASTING AVOIDS THE NEED TO ATTACH THROUGH shmat() in shm.h HEADER I GUESS.
M=(struct MemData*)mmap(NULL, sizeof(MemData), PROT_READ|PROT_WRITE, MAP_SHARED, SD, 0);
if(M== MAP_FAILED){
printf("mmap() error");
return EXIT_FAILURE;
}else{
printf("\n%s", M->FileName);
printf("\n%d", M->LastByteLength);
printf("\n%d", M->ReadPointer);
printf("\n%d", M->WritePointer);
}
/*
FILE *FP= fopen(FileName, "rb");
if(FP!= NULL){
unsigned long int FilePosition;
fseek(FP, 0, SEEK_SET);
FilePosition=ftell(FP);
fclose(FP);
}
*/
munmap(M,sizeof(MemData));
close(SD);
return 0;
}
答案 0 :(得分:2)
根据您的评论,问题是由于您分配和传递FileName
值的方式引起的。
M->FileName=(char*)"xaa";
这将导致M->FileName
在编写器进程的内存中持有指向字符串的指针。在读取器进程中取消引用此指针会导致分段错误,原因是文件名存储在写入器进程内存中,而文件名未与读取器共享。您需要将字符本身存储在共享内存中,而不是指向编写器进程内存的指针。
如果可以安全地假定文件名字符串的最大长度,则可以更改结构以存储整个字符串而不是指针:将char* FileName;
更改为char FileName[256];
或其他一些固定长度的值。进行此更改后,您将需要使用strcpy
而不是直接分配:将M->FileName=(char*)"xaa";
更改为strcpy(M->FileName, "xaa");
。
如果需要动态长度的字符串,可以再次调用mmap
为该字符串分配共享内存,然后将指向此共享内存字符串的指针存储在FileName
中。