程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> mmap報錯Invalid argument的解決辦法

mmap報錯Invalid argument的解決辦法

編輯:C++入門知識

mmap這個函數到處都用到,很多問題都是用perror("mmap")出來的結果是Invalid argument

這個問題,我遇到有兩種可能導致

1. open文件時的用的訪問模式如O_RDONLY, O_WRONLY, or O_RDWR和你mmap的模式如

 PROT_EXEC  Pages may be executed.

 PROT_READ  Pages may be read.

 PROT_WRITE Pages may be written.

 PROT_NONE  Pages may not be accessed.


不匹配。

 

2. 你mmap的文件所屬的文件系統,如果是網絡上的文件,linux是無法保證文件的一致性的,那麼MAP_SHARED所要求的語義就不能夠達到,這時就看你所需要的一致性要求了,如果你只需要在內存上操作,不需要保證munmap時把內存flush回文件的話,可以采用MAP_PRIVATE模式,而如果需要保證這種強的一致性要求的話,就必須要用到MAP_SHARED。

我發現我對VIRTUAL BOX共享文件夾下的文件進行mmap操作就不能夠保證這個MAP_SHARED,perror的出錯信息也報的是Invalid argument,實際上對於其他linux本機文件目錄上的文件,這個一致性是可以保證的,也就是說只要除了這種共享的文件,對其他文件進行這個操作是可以正常執行的。

 

下面附上一個我自己調好的例子

1. mywriteread.c

[cpp]
#include <sys/mman.h>  
       #include <sys/stat.h>  
       #include <fcntl.h>  
       #include <stdio.h>  
       #include <stdlib.h>  
       #include <unistd.h>  
 
       #define handle_error(msg) \  
           do { perror(msg); exit(EXIT_FAILURE); } while (0) 
 
int main(int argc, char * argv[]) 

        char * addr; 
        int fd; 
        int i; 
        struct stat sb; 
        off_t offset, pa_offset; 
        size_t length; 
        ssize_t s; 
        char * buf = "123456789abcdefghijkl"; 
 
           if (argc < 3 || argc > 4) { 
               fprintf(stderr, "%s file offset [length]\n", argv[0]); 
               exit(EXIT_FAILURE); 
           } 
 
 
        fd = open(argv[1],O_RDWR); 
        if(fd ==-1) 
                handle_error("open"); 
 
        if(fstat(fd,&sb) == -1) 
                handle_error("fstat"); 
 
        offset = atoi(argv[2]); 
        pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE)-1); 
 
  if(offset >= sb.st_size){ 
                fprintf(stderr,"offset is past end if file \n"); 
                exit(EXIT_FAILURE); 
        } 
 
        if(argc == 4){ 
                length = atoi(argv[3]); 
                if(offset + length > sb.st_size) 
                        length = sb.st_size - offset; 
        } 
        else{ 
                length = sb.st_size - offset; 
        } 
 
        printf("\tfile size is %d\n",sb.st_size); 
        printf("length = %d\t, mapped memory length = %d\t, pa_offset = %d\n",length,length + offset -pa_offset, pa_offset); 
        addr = mmap(NULL,length + offset - pa_offset, PROT_READ|PROT_WRITE, 
                        MAP_SHARED,fd,pa_offset); 
 
        if(addr == MAP_FAILED) 
                handle_error("mmap"); 
 
 
        memcpy(addr,buf,10); 
        printf("check write!\n"); 
        for(i = 0;i<10 ; i++){ 
        printf("new mem[%d] = %c\n",i, *(addr+i)); 
        } 
 
        printf("string test = %s\n",(char *)addr); 
 
        munmap(addr,length + offset - pa_offset); 
return 0; 

#include <sys/mman.h>
       #include <sys/stat.h>
       #include <fcntl.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char * argv[])
{
        char * addr;
        int fd;
        int i;
        struct stat sb;
        off_t offset, pa_offset;
        size_t length;
        ssize_t s;
        char * buf = "123456789abcdefghijkl";

           if (argc < 3 || argc > 4) {
               fprintf(stderr, "%s file offset [length]\n", argv[0]);
               exit(EXIT_FAILURE);
           }


        fd = open(argv[1],O_RDWR);
        if(fd ==-1)
                handle_error("open");

        if(fstat(fd,&sb) == -1)
                handle_error("fstat");

        offset = atoi(argv[2]);
        pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE)-1);

  if(offset >= sb.st_size){
                fprintf(stderr,"offset is past end if file \n");
                exit(EXIT_FAILURE);
        }

        if(argc == 4){
                length = atoi(argv[3]);
                if(offset + length > sb.st_size)
                        length = sb.st_size - offset;
        }
        else{
                length = sb.st_size - offset;
        }

        printf("\tfile size is %d\n",sb.st_size);
        printf("length = %d\t, mapped memory length = %d\t, pa_offset = %d\n",length,length + offset -pa_offset, pa_offset);
        addr = mmap(NULL,length + offset - pa_offset, PROT_READ|PROT_WRITE,
                        MAP_SHARED,fd,pa_offset);

        if(addr == MAP_FAILED)
                handle_error("mmap");


        memcpy(addr,buf,10);
        printf("check write!\n");
        for(i = 0;i<10 ; i++){
        printf("new mem[%d] = %c\n",i, *(addr+i));
        }

        printf("string test = %s\n",(char *)addr);

        munmap(addr,length + offset - pa_offset);
return 0;

2. b.data

[cpp]
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa 

aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 [root@localhost tryrw]# ./mywr b.data 0 10
        file size is 120                                                                                                                     
length = 10     , mapped memory length = 10     , pa_offset = 0                                                                              
check write!                                                                                                                                 
new mem[0] = 1                                                                                                                               
new mem[1] = 2                                                                                                                               
new mem[2] = 3                                                                                                                               
new mem[3] = 4                                                                                                                               
new mem[4] = 5                                                                                                                               
new mem[5] = 6                                                                                                                               
new mem[6] = 7                                                                                                                               
new mem[7] = 8                                                                                                                               
new mem[8] = 9                                                                                                                               
new mem[9] = a                                                                                                                               
string test = 123456789aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa


 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved