You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过ctypes在多线程中调用DLL是否可行?启动第二线程时脚本异常停止原因是什么

问题原因

首先明确:ctypes本身支持多线程调用DLL函数,你遇到的崩溃和退出是代码实现错误导致的,核心原因有3个:

  • DllMain中调用了非线程安全的IO函数:Windows执行DllMain时会持有全局加载器锁,printf这类CRT函数内部自带IO锁,当第二个线程启动触发DLL_THREAD_ATTACH通知时,两个锁发生冲突直接触发死锁或程序崩溃。
  • 重复加载DLL:你将ctypes.CDLL的加载逻辑写在了死循环内,每次循环都会重复调用系统API加载DLL,虽然系统只会增加DLL引用计数,但并发加载操作会放大DllMain的锁冲突概率。
  • 守护线程被强制终止:你创建的两个线程都设置了daemon=True,主线程在启动t2、打印完still here...后就会直接退出,所有守护线程会被操作系统强制杀死,表现为程序突然停止。

另外你DLL中test函数的静态变量a没有加同步保护,会存在计数错乱的竞态问题,但不会直接导致程序崩溃。

修复方案

1. 修改DLL代码

移除DllMain内所有非必要操作,给test函数加线程同步:

// ctypes-example.hpp
#pragma once
#include <windows.h>
#include <stdio.h>
extern "C" {
    void init(void);
    void cleanup(void);
    void test(void);
}

// ctypes-example.cpp
#include "ctypes-example.hpp"
static CRITICAL_SECTION cs;
static int a = 0;

// 单独抽离初始化逻辑,不要在DllMain里执行复杂操作
extern "C" void init() {
    InitializeCriticalSection(&cs);
    printf("Load working...\n");
}

extern "C" void cleanup() {
    DeleteCriticalSection(&cs);
    printf("Unload working...\n");
}

void test(void) {
    EnterCriticalSection(&cs);
    printf("Hello from dll: %i\n", a);
    ++a;
    LeaveCriticalSection(&cs);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
    return TRUE; // DllMain仅返回成功即可,不执行其他逻辑
}

2. 修改Python代码

全局只加载一次DLL,添加线程等待逻辑:

import ctypes
import threading
import time

# 全局仅加载一次DLL
my = ctypes.CDLL('/cygdrive/m/Workspace/py/src/cpp/ctypes-example.dll')
my.init.restype = None
my.init.argtypes = ()
my.test.restype = None
my.test.argtypes = ()
my.cleanup.restype = None
my.cleanup.argtypes = ()

# 初始化DLL资源
my.init()

def tfunc():
    while True:
        my.test()
        # 可加小幅休眠避免占满CPU,按需调整
        time.sleep(0.001)

t1 = threading.Thread(target=tfunc)
t2 = threading.Thread(target=tfunc)

t1.start()
time.sleep(1)
t2.start()

print('still here...')

# 等待线程执行,如需停止可按Ctrl+C终止
try:
    t1.join()
    t2.join()
finally:
    my.cleanup()

3. 编译命令保持原有逻辑即可

修改后程序即可正常在多线程下调用DLL函数,不会出现突然停止的问题。

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:45:03