cygwin下的共享内存区

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

  

本文适用于

Cygwin checkout-2008-09-28

vs2008

 

欢迎转载,但请保留作者信息

 

 

Cygwin使用了多块共享内存区,创建这些内存区的功能由open_shared函数完成:

void * __stdcall

open_shared (const char *name, int n, HANDLE& shared_h, DWORD size,

          shared_locations& m, PSECURITY_ATTRIBUTES psa, DWORD access)

{

     void *shared;

 

     void *addr;

     if (m == SH_JUSTCREATE || m == SH_JUSTOPEN)

         addr = NULL;

     else

     {

         addr = off_addr (m);

         VirtualFree (addr, 0, MEM_RELEASE);

     }

 

     char map_buf[MAX_PATH];

     char *mapname = NULL;

 

     if (shared_h)

         m = SH_JUSTOPEN;

     else

     {

         if (name)

              mapname = shared_name (map_buf, name, n);

         if (m == SH_JUSTOPEN)

              shared_h = OpenFileMapping (access, FALSE, mapname);

         else

         {

              shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa,

                   PAGE_READWRITE, 0, size, mapname);

              if (GetLastError () == ERROR_ALREADY_EXISTS)

                   m = SH_JUSTOPEN;

         }

         if (shared_h)

              /* ok! */;

         else if (m != SH_JUSTOPEN)

              api_fatal ("CreateFileMapping %s, %E.  Terminating.", mapname);

         else

              return NULL;

     }

 

     shared = (shared_info *)

         MapViewOfFileEx (shared_h, access, 0, 0, 0, addr);

 

     if (!shared && addr)

     {

         shared = (shared_info *) MapViewOfFileEx (shared_h,

              FILE_MAP_READ|FILE_MAP_WRITE,

              0, 0, 0, NULL);

#ifdef DEBUGGING

         system_printf ("relocating shared object %s(%d) from %p to %p", name, n, addr, shared);

#endif

         offsets[0] = 0;

     }

 

     if (!shared)

         api_fatal ("MapViewOfFileEx '%s'(%p), %E.  Terminating.", mapname, shared_h);

 

     if (m == SH_CYGWIN_SHARED && offsets[0])

     {

         ptrdiff_t delta = (caddr_t) shared - (caddr_t) off_addr (0);

         offsets[0] = (caddr_t) shared - (caddr_t) cygwin_hmodule;

         for (int i = SH_USER_SHARED + 1; i < SH_TOTAL_SIZE; i++)

         {

              unsigned size = offsets[i + 1] - offsets[i];

              offsets[i] += delta;

              if (!VirtualAlloc (off_addr (i), size, MEM_RESERVE, PAGE_NOACCESS))

                   continue;  /* oh well */

         }

         offsets[SH_TOTAL_SIZE] += delta;

     }

 

     debug_printf ("name %s, n %d, shared %p (wanted %p), h %p", mapname, n, shared, addr, shared_h);

 

     return shared;

}

对于父进程而言,其传递进来的句柄shared_hNULL,因此这个函数将调用CreateFileMapping创建一个共享内存区,而对于fork出来的子进程,其传递进来的句柄是从父进程复制而来,因此不为NULL,上述函数将直接用OpenFileMapping打开已经存在的共享内存区。

这些共享内存区的名称并不直接由name决定,而是由namen两个参数共同决定:

char * __stdcall

shared_name (char *ret_buf, const char *str, int num)

{

  __small_sprintf (ret_buf, "%s.%d", str, num);

  return ret_buf;

}

比如对于“shared”这块内存区,实际的名称将转换为“shared.5”。

open_shared函数中断下来,可以发现cygwin一共打开了下面几块共享内存区:

1.1    shared

这块内存区的名称为“shared”,创建时的调用栈如下

>     cygwin.dll!open_shared(const char * name=0x100efb80, int n=0x00000005, void * & shared_h=0x00000000, unsigned long size=0x000081a0, shared_locations & m=SH_CYGWIN_SHARED, _SECURITY_ATTRIBUTES * psa=0x101407bc, unsigned long access=0x00000006)  142      C++

      cygwin.dll!memory_init()  387 + 0x28 字节 C++

      cygwin.dll!dll_crt0_0()  847   C++

      cygwin.dll!dll_entry(void * h=0x10000000, unsigned long reason=0x00000001, void * static_load=0x0021fd30)  186       C++

      cygwin.dll!DllMain(HINSTANCE__ * h=0x10000000, unsigned long reason=0x00000001, void * ptr=0x0021fd30)  79       C++

      cygwin.dll!__DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0x00000001, void * lpreserved=0x0021fd30)  543 + 0x11 字节   C

      cygwin.dll!_DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0x00000001, void * lpreserved=0x0021fd30)  507 + 0x11 字节   C

1.2    S-1-5-21-1390067357-839522115-1343024091-1011

这块内存区的名称为“S-1-5-21-1390067357-839522115-1343024091-1011,创建时的调用栈如下

>     cygwin.dll!open_shared(const char * name=0x0021f50c, int n=0x00000001, void * & shared_h=0x00000000, unsigned long size=0x00004068, shared_locations & m=SH_USER_SHARED, _SECURITY_ATTRIBUTES * psa=0x101407a4, unsigned long access=0x00000006)  142      C++

      cygwin.dll!user_shared_create(bool reinit=false)  261 + 0x26 字节    C++

      cygwin.dll!memory_init()  389 + 0x7 字节   C++

      cygwin.dll!dll_crt0_0()  847   C++

      cygwin.dll!dll_entry(void * h=0x10000000, unsigned long reason=0x00000001, void * static_load=0x0021fd30)  186       C++

      cygwin.dll!DllMain(HINSTANCE__ * h=0x10000000, unsigned long reason=0x00000001, void * ptr=0x0021fd30)  79       C++

      cygwin.dll!__DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0x00000001, void * lpreserved=0x0021fd30)  543 + 0x11 字节   C

      cygwin.dll!_DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0x00000001, void * lpreserved=0x0021fd30)  507 + 0x11 字节   C

1.3    cygpid

这块内存区的名称为“cygpid”,创建时的调用栈如下:

>     cygwin.dll!open_shared(const char * name=0x100ee364, int n=0x00000180, void * & shared_h=0x00000000, unsigned long size=0x00008108, shared_locations & m=SH_MYSELF, _SECURITY_ATTRIBUTES * psa=0x00215da0, unsigned long access=0x00000006)  142      C++

      cygwin.dll!pinfo::init(int n=0x00000180, unsigned long flag=0x00000001, void * h0=0x00000000)  223 + 0x22 字节       C++

      cygwin.dll!set_myself(void * h=0x00000000)  53 C++

      cygwin.dll!pinfo_init(char * * envp=0x00000000, int envc=0x00000000)  94    C++

      cygwin.dll!dll_crt0_1(void * __formal=0x00000000)  952   C++

      cygwin.dll!_cygtls::call2(unsigned long (void *, void *)* func=0x10011ff0, void * arg=0x00000000, void * buf=0x00216fb8)  72 + 0xd 字节  C++

      cygwin.dll!_cygtls::call(unsigned long (void *, void *)* func=0x10011ff0, void * arg=0x00000000)  66  C++

      cygwin.dll!_dll_crt0()  1082 + 0xc 字节      C++

      cygwin.dll!cygwin_dll_init()  1121  C++

      bash.exe!main(int argc=0x00000003, char * * argv=0x00c567f0)  769 + 0x8 字节  C

1.4    NULL

这块内存区的名称为空,创建时的调用栈如下:

>     cygwin.dll!open_shared(const char * name=0x00000000, int n=0x00000000, void * & shared_h=0x00000000, unsigned long size=0x00000514, shared_locations & m=SH_SHARED_CONSOLE, _SECURITY_ATTRIBUTES * psa=0x101407bc, unsigned long access=0x00000006)  142      C++

 

      cygwin.dll!fhandler_console::get_tty_stuff(int flags=0x00010002)  76 + 0x26 字节  C++

      cygwin.dll!fhandler_console::cyg_open(int flags=0x00010002, unsigned int __formal=0x00000000)  594 + 0xb 字节       C++

      cygwin.dll!fhandler_console::init(void * f=0x00000003, unsigned long a=0xc0000000, unsigned int bin=0x00010000)  1812 + 0x1a 字节  C++

      cygwin.dll!dtable::init_std_file_from_handle(int fd=0x00000000, void * handle=0x00000003)  358 + 0x2a 字节       C++

      cygwin.dll!dtable::stdio_init()  170  C++

      cygwin.dll!dll_crt0_1(void * __formal=0x00000000)  1001  C++

      cygwin.dll!_cygtls::call2(unsigned long (void *, void *)* func=0x10011ff0, void * arg=0x00000000, void * buf=0x00216fb8)  72 + 0xd 字节  C++

      cygwin.dll!_cygtls::call(unsigned long (void *, void *)* func=0x10011ff0, void * arg=0x00000000)  66  C++

      cygwin.dll!_dll_crt0()  1082 + 0xc 字节      C++

      cygwin.dll!cygwin_dll_init()  1121  C++

      bash.exe!main(int argc=0x00000003, char * * argv=0x00c567f0)  769 + 0x8 字节  C

 

 

1       参考资料

cygwin下的user heap(2009-9-8)

cygwin下的cygheap:从父进程到子进程的复制(2009-9-7)

cygwin下的/etc/fstab(2009-9-7)

cygwin关键技术:fork(2009-9-4)

cygwin关键技术:设备模拟(2009-9-4)

cygwin关键技术cygheap(2009-9-2)

cygwin关键技术:tls(2009-8-24)

vs2008下使用cygwin23):stdinstdoutstderr(2008-10-21)

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌云阁主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值