精华内容
下载资源
问答
  • 自己写了一下动态库的两种调用方法. 时面有对应的说明。方法调用,DLL打包。
  • 封装动态库

    封装动态库

    展开全文
  • 【c++】求大神回复,我的动态库被别人使用多线程调用,我单线程调用了一个别人写的动态库,我调的这个库需不需要支持可重入,要不要加锁保护?我调的库,我把它当一个函数使用,它里面也挺复杂的,好多全局变量。
  • 动态链接的全局变量与多线程

    千次阅读 2018-09-30 16:48:16
    最近对多线程调用时,动态链接的全局变量有了以下几点认识。 1、动态链接被同一进程的多个线程加载时,全局变量的值是进程有效。  例如:动态链接C.dll有一个全局变量 int g_iCount=0(初始值)。某一函数...

    最近对多线程调用时,动态链接库的全局变量有了以下几点认识。

    1、动态链接库被同一进程的多个线程加载时,全局变量的值是进程有效。

       例如:动态链接库C.dll有一个全局变量 int g_iCount=0(初始值)。某一函数Method_D被调用一次,则g_iCount++。

                  当某一进程加载C.dll后,线程A、B先后调用Method_D后,线程A获得的C.g_iCount=1,但线程B获得的C.g_iCount则是2。

        这是因为线程B调用Method_D前,g_iCount已经被线程A更改。

     

    2、虽然说动态链接库的全局变量是进程级的,但并不是说 同一进程里,不同模块定义同名全局变量就可以互相传递数值。

         这跟我们的函数一样,即使在同一进程空间里,定义成相同名字跟结构,只要没有做导出,外部模块还是不能调用的。

         所以,如果想在同一进程的不同线程间共享某一数据,也可以在全局变量定义时,使用_declspec(dllexport) 将其导出,

          在调用处使用GetProcAddress()取得其在进程空间的地址来使用。

    展开全文
  • 好用的c++多线程软件 Pthread visual studio可用,mfc可用
  • 本文讨论了基于VC开发环境的异步串行通信动态链接的开发、设计过程,基于本文的动态链接,在开发的监控安防项目中上位机访问组网的控制器时,工作良好。
  • C/C++:多线程下使用dlopen、dlsym、dlclose装载动态库

    C/C++:多线程下使用dlopen、dlsym、dlclose装载动态库

    当在多线程下dlopen同一个动态库,使用的会是同一个动态库实例还是不同的动态库实例呢?

    count.h

    #ifndef _COUNT_H
    #define _COUNT_H
    
    #include <pthread.h>
    
    int count;
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
    
    int get();
    void inc();
    
    #endif
    

    count.c

    #include "count.h"
    
    int get()
    {
        return count;
    }
    
    void inc()
    {
        pthread_mutex_lock(&mutex);
        count++;
        pthread_mutex_unlock(&mutex);
    }
    
    编译生成libcount.so

    main.c

    #include <stdio.h>
    #include <dlfcn.h>
    #include <pthread.h>
    
    #define NUM 1000 
    #define LIBPATH "/home/test1280/libcount.so"
    
    static const char *threadA = "Thread-A";
    static const char *threadB = "Thread-B";
    
    void *ThreadRun(void *arg)
    {
        usleep(500*1000);
        printf("Start:%s\n", (char *)arg);
    
        void *handler = dlopen(LIBPATH, RTLD_LAZY);
        if (handler == NULL)
        {
            printf("ERROR:%s:dlopen\n", dlerror());
        }
    
        void (*inc)() = (void (*)())dlsym(handler, "inc");
        if (inc == NULL)
        {
            printf("ERROR:%s:dlsym\n", dlerror());
        }
    
        int i = 0;
        for (; i < NUM; i++)
        {
            inc();
        }
    
        int (*get)() = (int (*)())dlsym(handler, "get");
        if (get == NULL)
        {
            printf("ERROR:%s:dlsym\n", dlerror());
        }
        printf("INFO:%s:get() return %d\n", (char *)arg, get());
    
        dlclose(handler);
    }
    
    int main()
    {
        pthread_t tid1;
        pthread_t tid2;
    
        pthread_create(&tid1, NULL, ThreadRun, (void *)threadA);
        printf("create Thread-A OK!!!\n");
        pthread_create(&tid2, NULL, ThreadRun, (void *)threadB);
        printf("create Thread-B OK!!!\n");
    
        while (1);
    
        return 0;
    }
    
    [test1280@localhost ~]$ gcc -o main main.c -ldl -lpthread
    [test1280@localhost ~]$ ./main
    create Thread-A OK!!!
    create Thread-B OK!!!
    Start:Thread-A
    INFO:Thread-A:get() return 1000
    Start:Thread-B
    INFO:Thread-B:get() return 1000
    ^C
    

    这么看来同一进程实体不同线程dlopen相同的库会得到不同的实例?

    一个动态库会在同一进程同一时刻同时被加载多次?

    当然不对啦!

    那按照我们期待的,希望输出的最后的值应该是2000,那为何是1000呢?

    原因:

    线程A或者线程B跑的太快了,在一个时间片内就已经做完:
    1.装载动态库到当前进程;
    2.获得函数地址;
    3.调用inc指定次数;
    4.输出get返回值;
    5.dlclose卸载动态库;

    注意:

    dlclose时,此时此刻可能仅仅只有一个线程在跑着,另一个线程还没有dlopen那个动态库,此时只有一个线程持有libcount.so的句柄,然后做完所有操作,dlclose,发现对库的引用减少至0,就将libcount.so从当前进程卸载;

    然后呢,就是另一个线程在跑,再打开dlopen同一个动态库,然后里面的全局变量(库内全局)静态初始化为0,然后inc,然后…

    结果很明显:是由于某个线程跑的太快,导致另一个线程还没有执行dlopen时,前一个进程已经做完所有活了(包括卸载libcount.so库),当另一个线程执行dlopen时,完全不知道这个库曾经被加载到当前进程…于是库中全局变量又静态初始化…

    这样的时序看来,输出两个1000合情合理.

    如何验证我们刚刚说的时序呢?

    修改下main.c:

    #include <stdio.h>
    #include <dlfcn.h>
    #include <pthread.h>
    
    #define NUM 1000 
    #define LIBPATH "/home/test1280/libcount.so"
    
    static const char *threadA = "Thread-A";
    static const char *threadB = "Thread-B";
    
    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
    void *ThreadRun(void *arg)
    {
        usleep(500*1000);
        printf("Start:%s\n", (char *)arg);
    
        void *handler = dlopen(LIBPATH, RTLD_LAZY);
        if (handler == NULL)
        {
            printf("ERROR:%s:dlopen\n", dlerror());
        }
    
        void (*inc)() = (void (*)())dlsym(handler, "inc");
        if (inc == NULL)
        {
            printf("ERROR:%s:dlsym\n", dlerror());
        }
    
        int i = 0;
        for (; i < NUM; i++)
        {
            inc();
        }
    
        int (*get)() = (int (*)())dlsym(handler, "get");
        if (get == NULL)
        {
            printf("ERROR:%s:dlsym\n", dlerror());
        }
        printf("INFO:%s:get() return %d\n", (char *)arg, get());
    
        pthread_mutex_lock(&mutex);
        dlclose(handler);
        printf("INFO:lib unload && %s END...\n", (char *)arg);
        pthread_mutex_unlock(&mutex);
    }
    
    int main()
    {
        pthread_t tid1;
        pthread_t tid2;
    
        pthread_create(&tid1, NULL, ThreadRun, (void *)threadA);
        printf("create Thread-A OK!!!\n");
        pthread_create(&tid2, NULL, ThreadRun, (void *)threadB);
        printf("create Thread-B OK!!!\n");
    
        while (1);
    
        return 0;
    }
    
    [test1280@localhost ~]$ gcc -o main main.c -ldl -lpthread
    [test1280@localhost ~]$ ./main
    create Thread-A OK!!!
    create Thread-B OK!!!
    Start:Thread-A
    INFO:Thread-A:get() return 1000
    INFO:lib unload && Thread-A END...
    Start:Thread-B
    INFO:Thread-B:get() return 1000
    INFO:lib unload && Thread-B END...
    ^C
    

    另外,我想看看两个线程对同一个库实例进行操作是什么效果…?

    我们只要让两个线程同时(同一时刻)对一个库保持打开状态即可(不dlclose):

    将ThreadRun中最后的dlclose删除,如下main.c所示:

    void *ThreadRun(void *arg)
    {
        usleep(500*1000);
        printf("Start:%s\n", (char *)arg);
    
        void *handler = dlopen(LIBPATH, RTLD_LAZY);
        if (handler == NULL)
        {
            printf("ERROR:%s:dlopen\n", dlerror());
        }
    
        void (*inc)() = (void (*)())dlsym(handler, "inc");
        if (inc == NULL)
        {
            printf("ERROR:%s:dlsym\n", dlerror());
        }
    
        int i = 0;
        for (; i < NUM; i++)
        {
            inc();
        }
    
        int (*get)() = (int (*)())dlsym(handler, "get");
        if (get == NULL)
        {
            printf("ERROR:%s:dlsym\n", dlerror());
        }
        printf("INFO:%s:get() return %d\n", (char *)arg, get());
    
        //delete...
        //dlclose(handler);
    }
    
    [test1280@localhost ~]$ ./main
    create Thread-A OK!!!
    create Thread-B OK!!!
    Start:Thread-A
    INFO:Thread-A:get() return 1000
    Start:Thread-B
    INFO:Thread-B:get() return 2000
    ^C
    

    当然,这个示例并不好,有dlopen,就应该有配套的dlclose,虽然如此,但是可以很好地验证我们的设想.

    结论:

    同一进程同一时刻,不同线程通过dlopen打开相同的动态库,只是把一份动态库装载到当前进程,进程中仅仅有一个动态库实例,动态库中全局变量对各个线程来说是“同一份”.

    同一进程不同时刻,不同线程虽然dlopen了,但是可能由于时序问题以及dlclose卸载动态库,存在多次加载动态库的情况,那么也就是从进程的整体生命周期来看是不同的库实例了,库中的全局变量对于不同的线程,在不同的时间段来说是“不相同的”.

    同一时刻,一个进程内仅仅有同一个动态库实例哦.

    展开全文
  • C语言多线程,动态库和静态库

    千次阅读 2016-06-11 10:52:38
    C语言多线程,动态库和静态库

    1 初识多线程

    通常一个进程(process)下都是并发运行着多个任务,例如360卫士可以扫描病毒的同时清理系统垃圾文件或者安装软件。而如果在不使用线程的情况下,程序都是按照某个顺序(从上到下,选择或者是循环)单线程运行,这样的效率通常都比较低,服务器得应用以及处理大型数据的程序都是多线程并发同时处理多个任务,这样能够充分利用系统资源,更加高效的完成任务。

    单线程VS多线程

    单线程同步打开五个对话框:

    #include <Windows.h>
    #include <process.h>
    #include <stdlib.h>
    
    //进程:加载到内存中的程序,至少有一个线程在运行,通常是多线程并发运行
    //单线程 程序代码按照同步依次从上到下执行
    //多线程 程序代码按照异步乱序执行
    
    
    /*
        单线程显示5个对话框
        @author Tony 18601767221@163.com
        @since 2016060610 15:33
    */
    void show_dialog() {
    
        //如果没有启动多线程则是同步打开五个窗口,一个接着一个按照顺序打开
        for (int i = 0; i < 5; i++) {
            MessageBoxA(0, "单线程执行", "显示对话框", 0);
        }
    
    }
    
    /*
        主线程入口
        @author Tony 18601767221@163.com
        @since 20160609  07:43
    */
    void main() {
        show_dialog();
        system("pause");
    }

    多线程同时打开五个对话框:

    /*
        定义线程任务
        @author Tony 18601767221@163.com
        @since 20160609  07:45
    */
    void run(void *p) {
    
        //如果没有启动多线程则是同步打开五个窗口,run方法为普通的方法,而不是作为线程的入口
    
    
            MessageBoxA(0, "多线程执行", "显示对话框", 0);
    
    }
    
    /*
        主线程入口
        @author Tony 18601767221@163.com
        @since 20160609  07:43
    */
    void main() {
        for (int i = 0; i < 5;i++) {
            //启动线程  
            _beginthread(run, 0, NULL);//把run函数当做线程的入口点
        }
    
        system("pause");
    }

    2初识动态库

    动态库可以作为一个组件,通过工具植入到应用程序当中。
    在使用VS2015开发应用程序时,默认生成的都是和项目名称保持一致的可执行程序(例如HelloWorld.exe),而除了.exe之外还可以选择以动态链接库(.dll)的方式生成和以静态链接库(.lib)的方式生成。
    程序生成格式

    如何编写一个dll?看如下程序

    
    #include <Windows.h>
    //预编译时去掉DOS窗口
    #pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
    
    
    /*
        dll模块注入
            需要先将项目属性的配置类型改成动态链接库(.dll),dll运行时不需要main函数
            只需要通过工具将其注入到其他进程中即可
        @author Tony 18601767221@163.com
        @since 20160609 08:04
    */
    //导出接口
    _declspec(dllexport) void module() {
    
        MessageBoxA(0, "李彦宏请你到百度去喝茶", "百度系统消息", 0);
    
    
        for (int i = 0; i < 200;i++) {
    
            malloc(1024*1024*20); //每次循环吃20M内存
        }
    }

    编写完成之后需要将项目默认值的配置类型改为dll,更改输出的dll目标文件名,然后重新生成包含dll模块的源程序,再通过dllinject工具配置dll文件路径和函数名称就可以注射到其他进程中。

    3初识静态库

    通常情况函数的声明都在头文件中,而函数的实现是在源文件中。如果要想调用一个第三方的库函数,咋办呢?

    这里首先实现一个简单的第三方库函数:
    在WindowsC的解决方案下新建一个名为WindowsCLibrary的项目
    我的项目结构如下:
    项目结构
    函数的声明(windowslib.h)如下:

    
    int add(int one, int two); //头文件声明函数

    函数的实现(windowslib.c)如下:

    
    int add(int one,int two) {
    
        return one + two; //返回两个整数的和即可
    }

    编写完头文件和源文件之后将项目设置配置类型为静态库(我这里设置的文件就是WindowsCLibrary.lib)
    静态库
    然后将编译生成后的头文件(windowsclib.h)以及库文件(WindowsCLibrary.lib)都复制到将要调用第三方库函数的项目的根目录下:(C:\Tony\WindowsC\WindowsC\WindowsC)
    复制头文件和库文件

    接下来就可以在WindowsC项目中引用WindowsCLibrary项目的函数了

    #include <stdio.h>
    #include <stdlib.h>
    #include "windowslib.h"
    
    #pragma comment(lib,"WindowsCLibrary.lib") //加载指定的模块
    
    void main() {
    
        int result = add(3, 5);
    
        printf(" result =%d ",result );
    
        for (int i = 0; i < result;i++) {
    
            //system("notepad");
        }
        system("pause");
    
    }

    欢迎扫描下方的二维码,关注微信公众服务号-艺无止境,分享IT技术干货。
    艺无止境

    展开全文
  • MFC多线程互斥锁的使用

    千次阅读 2019-10-04 23:14:12
    MFC多线程互斥锁的使用 本例演示在MFC中使用多线程。第一部分实现多线程的开启、暂停、继续、注销(见上一篇文章MFC多线程的开启、暂停、继续和注销)。第二部分实现两个线程互斥锁的使用。 演示系统为Win10,平台为...
  • 1、csharp的代码被生成dll; 2、dll内部存在某些方法,它的执行流程中存在多线程的操作; 3、这种情况下,dll能够正常使用么?
  • VC++动态链接编程之多线程

    千次阅读 2008-09-16 18:30:00
    (4)动态库错误函数,函数原型: //共享对象操作函数执行失败时,返回出错信息 const char *dlerror(void); 从这里我们分明看到Windows API――LoadLibrary、FreeLibrary和GetProcAddress的影子!又一个"万...
  • Qt多线程程序发布需要用到这个动态库,支持Qt5以后的版本,mingw版本
  • 2、COM组件是以WIN32动态链接(DLL)或可执行文件(EXE)形式发布的可执行代码组成。 3、COM组件是遵循COM规范编写的 4、COM组件必须是动态链接的 5、COM组件不是一种计算机语言 6、COM组件不是DLL,只是利用DLL来给...
  • dll的多进程多线程安全的几种策略

    千次阅读 2013-07-08 10:39:06
    1、动态库只有一个导出函数。 这种情况非常少,也是最容易处理的情况。这种情况下编写函数时,只需要考虑不要有冲突的全局数据就可以了。这里的全局数据包括了在堆中分配的数据块和静态全局变量等。如果存在这样...
  • 封装基础的QTcpSocket、QThread...服务器监听后,每新来一个连接起一个线程,完全线程独立; 通过socketDescrptor传递socket; 不建议工程中使用该种模式,这只是一个简单的demo学习了解即可; 实际工程开发建议boost;
  • 多线程动态链接.rar

    2008-11-30 15:00:44
    多线程的网络编程链接,简单的教程。适用于初学者
  • 心智 简单的多线程 C++ IRC 机器人,带有基于动态库的模块系统。
  • case DLL_PROCESS_ATTACH: //进程被调用 case DLL_THREAD_ATTACH: //线程被调用 case DLL_THREAD_DETACH: //进程被停止 ... } } 2动态链接和静态链接 1静态链接 静态链接的英文全称是Static Link Library它经
  • 多线程 图片显示 基本控件 动态链接 定时器 MFC
  • 多线程编程实现矩阵乘法

    热门讨论 2012-08-20 20:11:58
    1. 在Windows操作系统上,利用... 在上述两种环境下,实现相乘操作的两个矩阵均作为应用程序的输入参数动态生成,并输出计算结果。  4. 在程序实现过程中,要求每个乘积矩阵元素的计算过程均由一个独立的线程实现。
  • 和其它多线程一样,不能在IDE环境调试,只能编译EXE后再调试。 特别声明:此DLL仅限于VB爱者研究使用,使用者请注明出处(首发于VBGOOD 链接地址http://www.vbgood.com/thread-108165-1-1.html),不得用于商业用途...
  • Linux 多线程 pthread初探

    千次阅读 2016-04-19 23:54:10
    Linux 多线程 pthread用法(一) Linux 多线程编程基介绍 Linux 线程有时候也叫 Light Weight Process LWP 轻量级线程,是进程的一个执行流,有自己的执行栈,是操作系统调度的最小单位。 多线程优势在于切换...
  • 调用第三方 多线程开发防止

    千次阅读 2013-12-03 15:24:44
    开发信用卡转账的问题集 ...在qt中应用动态库,需要在.pro文件中加入LIBS += -Lc:/gmc/qmf -lposinfqmf 说明:-LC:表示动态库.lib文件的路径,-l表示的是动态库.lib的名字。 2.头函数的编写  如果
  • C ++ 11多线程库。 该具有以下功能。 执行定期任务。 指定次数执行任务。 动态线程管理。 这个,它将为您带来多线程的乐趣。 测试执行程序。 $ cd executor/cmake $ cmake . $ cmake --build . $ ctest
  • 010动态连接 011多线程和对象同步 002从Win32到MFC 013ADO数据库编程
  • 访问路径为:http://localhost:8080/web001/test.do?flag=xxyyzz&switch=off 其中switch开关参数取值有两种:on和off,on表示执行线程对应的任务,off表示中断线程正在执行的任务。
  • 刚接触linux的多线程编程,总结基础知识并编写socket通信的多线程多进程代码,已经验证可行,包括共享队列、套接字、循环队列、Makefile编写、动态库静态库编译和使用等。具体代码请看多线程多进程的事例分享。
  • C/C++ 用 pthread 进行多线程开发

    万次阅读 2019-02-21 14:01:14
    多线程是实现多任务处理的一种最常用的手段,线程相比进程而言显得轻量级。 本文分享如何用 C 进行多线程开发。 核心在于 pthread 这个。 调用 pthread_create()函数就可以创建一个线程。 它的函数原型如下: #...
  • OpenGL多线程

    千次阅读 2016-08-25 19:06:17
    在OpenGL里面使用多线程加载纹理是很美好的构想。网上讨论这个的并不多。中文博客里 http://www.cnblogs.com/mazhenyu/archive/2010/04/29/1724190.html参考了某个老外的尝试:...
  • JAVA多线程并发

    千次阅读 多人点赞 2019-09-18 12:14:29
    JAVA多线程并发1 JAVA并发知识2 JAVA 线程实现/创建方式2.1 继承 Thread 类2.2 实现 Runnable 接口2.3 Callable 、Future 、ExecutorService 有返回值线程2.4 基于线程池的方式2.4.1 4种线程池2.4.1.1 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 230,695
精华内容 92,278
关键字:

动态库多线程