我正在将 FORTRAN/C 中的一个程序移植到 cygwin,该程序依赖于 C 例程来创建共享内存区域,允许各种独立的 FORTRAN 例程共享数据。程序可以在 Linux 上使用 g77/gcc 编译器编译并正常运行。我正在 cygwin 1.7.33-2(0.280/5/3) 上使用 gfortran/gcc (4.8.3) 进行编译。
一个 C 例程创建用户定义大小的共享内存部分。这似乎工作得很好,尽管我必须在 sys/shm.h 文件中添加两行:
#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
shm 库函数似乎返回合理的信息(页面大小)。
然后,每个 FORTRAN 例程调用一个 C 例程来查找共享内存,其中 C 例程返回指向用于不同类型数据的部分中的两个位置的指针:
#define PAGESIZE 1024
int findshm(
char **pptr, /* Address of the parameter pointer */
float **cptr) /* Address of the data pointer */
.... calls to shm library functions ....
shmaddr = 0;
p = shmat(shmid, shmaddr, (SHM_R | SHM_W));
/* Store the pointers */
*pptr = p;
*cptr = (float *) (p + PAGESIZE);
return npages;
调用 FORTRAN 代码如下所示:
integer pptr, cptr
integer npages
npages = findshm(pptr, cptr)
虽然创建的内存部分npages
的总大小还可以,但是在cygwin上,cptr后面的内存量太小(但在Linux中则不然),并且对于较大的数据集,程序会崩溃
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
认为这可能与 C 代码和 FORTRAN 代码中指针的不同基础数据类型(整数、字符/浮点)有关,我尝试将 FORTRAN 例程中指针的类型定义更改为
byte pptr
real*4 cptr
它全部编译并运行,但给出了完全相同的运行时错误,并且没有解释为什么该程序在 Linux 中运行。
不确定此时我能做什么(要注意什么,从哪里获得帮助),所以欢迎输入。
编辑
事实证明,在代码中标记的部分
.... calls to shm library functions ....
有一条线
shmid = shmget(key, PAGESIZE, IPC_ALLOC);
使用之前定义为 PAGESIZE=512
和 IPC_ALLOC=0
的参数,导致了问题。 Linux 中的调用似乎返回与 key 关联的 shmid,而不执行内存分配,而在 cygwin 中,它会导致内存分配达到 4k 的限制,从而导致 seg 错误。
最佳答案
该问题已被 cygwin 程序员解决。它涉及 cygwin1 DLL 的补丁,尽管可以通过传递有关 shm 部分大小的附加信息来解决问题。
关于c - cygwin 中混合 C/FORTRAN 程序的共享内存处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29512185/