文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>非线程安全共享库动态加载实现线程安全

非线程安全共享库动态加载实现线程安全

时间:2010-05-21  来源:ssddyb

1、 linux 动态库剖析-IBM

    问题描述如下:现有一个共享库,不是线程安全的,但是需要使其多线程运行。这里提供一个简便的解决方案:将该共享库拷贝多份,使用不同的名字,然后在开启每个线程的时候动态加载共享库,然后在调用库的函数即可实现多线程运行。
   
这里自己试了个例子:

//dltest.cpp

#include "myso.h"
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>^M#include <pthread.h>
int featurethread_count = 0;
static int libnum = 1;
pthread_mutex_t featurethread_count_mutex = PTHREAD_MUTEX_INITIALIZER;^M
void* FeatureThread( void* p )^M
{
   const char *dlError;
   void *PornLib;
   char lib[10];
   pthread_mutex_lock(&featurethread_count_mutex);
   sprintf(lib, "./libmyso%d.so", libnum);
   libnum++;
   PornLib = dlopen(lib, RTLD_LAZY);
   dlError = dlerror();
  // fprintf(stderr, "%s \n", dlError);

   pthread_mutex_unlock(&featurethread_count_mutex);
   void (*sofun) (ssd &) ;
   *(void**)(&sofun) = dlsym(PornLib, "test");
    dlError = dlerror();
  // fprintf(stderr, "%s \n", dlError);

   ssd myssd1;
   while(1)
   {
     sofun(myssd1);
     fprintf(stdout, "%s \n", lib);
   }
}

int main()
{
      pthread_t tmp ;
      pthread_create(&tmp,NULL,FeatureThread,NULL);
      pthread_create(&tmp,NULL,FeatureThread,NULL);
      pthread_create(&tmp,NULL,FeatureThread,NULL);
      pthread_create(&tmp,NULL,FeatureThread,NULL);
      while(1);
}

g++ -o dltest dltest.cpp -lpthread -ldl

动态库如下:


//myso.h

struct ssd
{
  int *my_own;
  void ssd_new();
};
extern "C" void test(ssd &);



//myso.cpp
#include "myso.h"
#include <stdio.h>
#include <unistd.h>

void test1()
{
     sleep(1);
}
  void ssd::ssd_new()
  {
     my_own = new int[10];
      for(int j =0; j < 10; j++)
      {
    
         my_own[j] = j;
       }
       test1();
       delete[] my_own;
  }
struct ssd myssd;
static int i = 0;
void test (ssd&myssd1)
{
   while(++i < 10)
    {
      myssd1.my_own = new int[10];
       for(int j =0; j < 10; j++)
      {
         myssd1.my_own[j] = j;
       }
       delete[] myssd1.my_own;
      printf("new delete %d\n", i);
      myssd.my_own = new int[10];
      for(int j =0; j < 10; j++)
      {
         myssd.my_own[j] = j;
       }
       delete[] myssd.my_own;
     }
     i= 0;
     myssd.ssd_new();
}


g++ -rdynamic -shared -o libmyso1.so  myso.cpp
(*项 -rdynamic 用来通知链接器将所有符号添加到动态符号表中,目的是能够通过使用 dlopen 来实现向后跟踪。-ldl 表明一定要将 dllib 链接于该程序。*见文章开头链接中介绍)
然后拷贝4份libmyso1.so,分别命名为libmyso2.so、libmyso3.so、
libmyso4.so。
这样就可以多线程运行动态库中的代码。
运行的时候,使用gdb调试时,你会发现每个动态加载的共享库里的全局变量具有不同的地址。

【注意】:不能在生成可执行文件时链接该动态库,否则达不到并行效果,此时几个动态加载的共享库里的全局变量将会同一个。

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载