我将FORTRAN / C中的程序移植到cygwin,该程序依赖于C例程来创建共享内存区域,允许各种独立的FORTRAN例程共享数据。程序使用g77 / gcc编译器在Linux上编译并运行正常。我正在使用gfortran / gcc(4.8.3)编译cygwin 1.7.33-2(0.280 / 5/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
的总大小没问题,但cptr后面的内存量对于cygwin来说太小了(但在Linux中却没有),并且程序因较大的数据集而崩溃
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
认为它可能与C与FORTRAN代码中指针的不同底层数据类型(整数vs char / float)有关,我尝试将FORTRAN例程中指针的类型定义更改为
byte pptr
real*4 cptr
并且它都编译并运行,但是给出了完全相同的运行时错误,并没有解释为什么程序在Linux中有效。
不知道我在这一点上能做些什么(需要注意什么,在哪里获得帮助),所以输入值得赞赏。
编辑
事实证明,在标有
的代码部分 .... calls to shm library functions ....
有一行
shmid = shmget(key, PAGESIZE, IPC_ALLOC);
以前定义为PAGESIZE=512
和IPC_ALLOC=0
的参数导致了问题。 Linux中的调用似乎返回与密钥关联的shmid而不执行内存分配,而在cygwin中,它会导致内存分配到4k的限制,从而导致seg错误。
答案 0 :(得分:0)
cygwin程序员解决了这个问题。它涉及一个cygwin1 DLL的补丁,虽然可以通过传递有关shm部分大小的其他信息来解决。