6

我有一个与许多库链接的程序。我在分析器上运行我的应用程序,发现在一些网络请求之后大部分时间都处于“等待”状态。这些请求是我sleeping_function()从外部库调用代码的结果。我在一个循环中调用这个函数,该循环执行了很多次,所以所有的等待时间总计很大。

由于我无法修改,sleeping_function()我想启动一些线程来并行运行我的循环的一些迭代。问题是这个函数在内部使用了一些全局变量。

有没有办法告诉 SunOS 上的链接器我想以一种将它们中的所有变量放在线程本地存储中的方式链接特定库?

4

2 回答 2

2

我认为您无法仅使用链接器来实现此目的,但是您也许可以使用 C 中的某些代码来获得一些东西。

问题是调用加载已加载的库将返回对已加载实例的引用,而不是加载新副本。快速查看dlopenLoadLibrary的文档似乎可以确认没有办法多次加载同一个库,至少如果您希望准备执行图像时不会。避免这种情况的一种方法是防止操作系统知道它是同一个库。为此,您可以制作该文件的副本。

一些伪代码,只需将调用替换为sleeping_function调用call_sleeping_function_thread_safe

char *shared_lib_name

void sleeping_function_thread_init(char *lib_name);

void call_sleeping_function_thread_safe()
{
  void *lib_handle;
  pthread_t pthread;
  new_file_name = make_copy_of_file(shared_lib_name);

  pthread_create(&pthread, NULL, sleeping_function_thread_init, new_file_name);
}

void sleeping_function_thread_init(char *lib_name)
{
  void *lib_handle;
  void (*)() sleeping_function;

  lib_handle = dlopen(lib_name, RTLD_LOCAL);
  sleeping_function = dlsym(lib_handle, "sleeping_function")
  while (...)
    sleeping_function;
  dlclose(lib_handle);
  delete_file(lib_name);      
}

对于 windowsdlopen成为LoadLibrarydlsym成为GetProcAddress等等......但基本的想法仍然有效。

于 2010-09-15T14:07:45.853 回答
0

一般来说,这是一个坏主意。全局数据并不是唯一可能阻止非线程安全库在多线程环境中运行的问题。

举个例子,如果库有一个全局变量指向一个内存映射文件,它总是映射到一个单一的硬编码地址。在这种情况下,使用您的技术,每个线程将有一个全局变量,但它们都将指向相同的内存位置,这将被多线程访问丢弃。

于 2010-09-15T14:14:49.770 回答