【问题标题】:address space Library or Process地址空间库或进程
【发布时间】:2010-06-29 05:31:16
【问题描述】:

我有一个基本的疑问。 我有一个使用共享库的进程。如果我在库中分配一些内存 那么它是哪个地址空间。 (库或进程) 在我看来,它是进程地址空间,因为一旦附加了库,它就全部在进程地址空间中。

如果我错了,请纠正我。

谢谢 阿皮特

【问题讨论】:

    标签: c linux memory shared-libraries


    【解决方案1】:

    库没有自己的地址空间。它被映射到某个进程中并在其中执行。所以你是对的。共享库的内存分配是在使用它的进程内部完成的。

    【讨论】:

      【解决方案2】:

      听起来您可能对地址空间和堆感到困惑。

      一个进程有一个地址空间,进程内的所有东西(主可执行文件、任何共享库和任何静态库)都共享一个地址空间。

      虽然在单个地址空间中可能存在多个堆,但 glibc 的实现方式是只有一个标准堆(标准堆,我指的是您通过 malloc/free 访问的堆)。这与 Windows 不同,在 Windows 中,可执行文件和 dll 可能各自拥有自己的堆(尽管再次共享一个地址空间)。

      【讨论】:

        【解决方案3】:

        库本身没有内存空间,因为它不是一个正在运行的进程。共享库的概念是拥有代码指令的共享副本,而不是该代码使用或生成的任何数据的共享副本。

        例如,如果您的库旨在管理动态分配的结构:

        object.h

         struct object_struct {
                char *name; 
                int foo;
                int bar;
         };
        
         typedef struct object_struct * object_t; /* opaque pointer */
        
         object_t new_object (char *name, int foo, int bar);
         void delete_object(object_t);
         int dump_object(object_t);
        

        object.c

          #include <stdio.h>
          #include "object.h"    
        
          object_t new_object (char *_name, int foo, int bar) {
               object_t _p = malloc(sizeof(object_t);
               if (!_p) 
                     return NULL;
               _p->foo = foo; _p->bar = bar;
               _p->name = strdup(_name);
               return _p;
          } 
        
          void delete_object(object_t p) {
               if(_p->name) 
                  free(_p->name);
        
               if(_p) 
                   free(_p);
          }
        
          int dump_object(object_t p) {
               FILE * fp = fopen(p->name, "w");
               if ( !fp ) 
                    return -1;
               fprintf(fp, "foo: %d\nbar: %d\n", p->foo, p->bar);
               fclose(fp);
               return 0;
          }
        

        您有两个程序 consumer1.c 和 consumer2.c 使用该库对象,如下所示:

        consumer1.c

         #include "object.h"
        
         int main() {
              object_t o = new_object("consumer1.txt", 1, 2);
              dump_object(o);
              delete_object(o);
              return 0;
         }
        

        consumer2.c

         #include "object.h"
        
         int main() {
              object_t o = new_object("consumer2.txt", 1, 2);
              dump_object(o);
              delete_object(o);
              return 0;
         }
        

        出于所有意图和目的,对象库的这两个程序不会有任何公共数据或公共内存或公共空间。

        P.S.:假设 gcc 和 gnu make,这里有一个 make 文件供你测试。

        生成文件

        default: libobject.a consumer1 consumer2
        
        .c.o: %.c
            $(CC) -c -o $@ $<
        
        libobject.a: object.o
            $(AR) r $@ object.o
        
        
        object.o: object.c object.h
        
        consumer1 consumer2: $@.o libobject.a
            $(CC) -o $@ $@.o -L. -lobject 
        

        P.P.S:这只是一个指南!我还没有在这里测试过代码,希望它一切顺利,但是,带着一粒盐,如果我犯了语法错误,请适当地修复。

        【讨论】:

          【解决方案4】:

          共享库可以与许多进程链接,并在这些进程的上下文中运行。

          假设您有一个共享库来发送 http 请求。浏览器进程和桌面应用程序都可以与该库链接,但进程上下文将使它们能够发送独立的请求,尽管它们都加载了相同的库。

          因此进程上下文决定了内存的分配,无论它是写在哪里(进程或库)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-07-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多