2024年最新Python调用C库及进程形式启动C的线程_py调用c 再次启动进程,2024年最新狂刷200道数据结构与算法

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

        else:
            print("testDLL:qR.get() %i" % v)
    qS.put("testDLL")

def testDLL_1(qR, qS):
pDll_1.startC()
while 1:
time.sleep(1)
#注意队列get是阻塞的,因此要先判断队列是否有值防止堵塞
#操作逻辑是如果是进程testDLL_1 取到队列值为1则不进行处理并放回队列,队列是线程安全的
while qR.qsize():
print(“testDLL_1:qR.size() > 0”)
v = qR.get()
if v == 1:
print(“testDLL_1:qR.get() %i” % v)
qR.put(v)
break
else:
print(“testDLL_1:qR.get() %i” % v)
qS.put(“testDLL_1”)

if name == ‘main’:
ProcessJob = []
qGet = multiprocessing.Queue() #队列是线程进程安全的无需加锁
qSen = multiprocessing.Queue()
p = multiprocessing.Process(target=testDLL_1, args=(qGet,qSen,))
ProcessJob.append§
p.start() # 启动进程
#p.join() # 阻塞进程直至 当前进程中的任务完成
p1 = multiprocessing.Process(target=testDLL, args=(qGet,qSen,))
ProcessJob.append(p1)
p1.start() # 启动进程
#p1.join() # 阻塞进程直至 当前进程中的任务完成

count = 0
while 1:
    qGet.put(10)    #往Get队列中放值10
    count += 1
    while qSen.qsize():     #每次取值应该都取完
        str = qSen.get()  # 从Sen队列中取值,是那两个线程放入的
        print("qSen : %s" % str)
    # 往Get队列中放值1,在testDLL进程中接收到1会设置CDLL的flag值从而改变线程执行,而testDLL1接收1则不做处理又再将1放入进去
    if count == 10:
        qGet.put(1)
    time.sleep(1)

C++代码



.h文件
extern “C” __declspec(dllexport) void startC();
extern “C” __declspec(dllexport) void SetFlagValue(int v);
.cpp文件
#include “pythonTestCDll.h”
#include
#include
#include
using namespace std;

thread *th = NULL;

void func()
{
int num = 0;
while (true)
{
cout << “startC num :” << num++ << " flag = " << flag << endl;
_sleep(1000);
if (flag == 1) //如果flag为1了那么就将num设置为0
{
num = 0;
}
//int re = 1 / num;
}
return;
}

void startC()
{
th = new thread(func);
/*while (1)
{
_sleep(10000);
}
*/
return;
}

void SetFlagValue(int v)
{
cout << "SetFlagValue flag : " << flag << "v = "<< v << endl;
flag = v;
cout << "SetFlagValue flag : " << flag << endl;
}


### 5、以类多个文件的管理形式实现进程multiprocessing方式的


from DllClass import MyClass 即可导入DllClass 文件中的MyClass  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/fe16e437f3794c6f802afae64a5b434f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAencxOTk2,size_20,color_FFFFFF,t_70,g_se,x_16)


python代码



DllClass.py文件
class MyClass:
#成员变量
name = ‘’
id = 0
state = 0
pDll = 0
# 构造函数
def __init__(self, name, id, state):
self.name = name
self.id = id
self.state = state

#成员方法
def getState(self):
    return self.state

def pocD(self, name):
    return

DllScoketClass.py文件
from ctypes import *import time
from multiprocessing import Queue
from DllClass import MyClass

class DllScoketClass(MyClass):
soc = ‘’
def __init__(self, soc, name, id, state):
super(DllScoketClass, self).__init__(name, id, state) #需显示调用父类__init__构造函数
self.soc = soc

def pocD(self, qR, qS):
    pDll = CDLL("./pythonTestCDll.dll")
    pDll.startC() #启动Cdll的线程
    #处理逻辑
    while 1:
        time.sleep(1)
        #接收守护进程中对队列传递的参数
        if qR.qsize() > 0:
            v = qR.get()
            print("DllScoketClass:qR.size() > 0")
            if v == 1:
                pDll.SetFlagValue(1) #调用CDLL的函数改变其中流程
        else:
            print("DllScoketClass:qR.size() < 0")
        qS.put("DllScoketClass")
    end

main.py文件
import os
import time
import multiprocessing
from DllScoketClass import DllScoketClass #从DllClass.py中导入MyClass类

if name == ‘main’:
c1 = DllScoketClass(“soc”, “c1”, 0, 0)
c2 = DllScoketClass(“soc2”, “c2”, 0, 0)
print(“父类方法: %i” % c1.getState())
ProcessJob = []
qGet = multiprocessing.Queue()
qSen = multiprocessing.Queue()
p = multiprocessing.Process(target=c1.pocD, args=(qGet, qSen, ))
ProcessJob.append§
p.start() # 启动进程
p = multiprocessing.Process(target=c2.pocD, args=(qGet, qSen,))
ProcessJob.append§
p.start() # 启动进程

count = 0
while 1:
    if qSen.qsize() > 0:    #防止get阻塞进程
        str = qSen.get()
        print("qSen : %s" % str)
    if count == 10:
        qGet.put(1)
    count += 1
    time.sleep(1)
end

C++代码与上节一致


### 6、如Cdll崩溃需由multiprocessing再次调起


如果Cdll崩溃那么其实调用Cdll的子进程的状态也是死亡了那么就可以根据判断子进程的状态判断是否奔溃,从而进行再次调起子进程从而再次调起Cdll线程。  
 python代码,只有main.py代码的main函数的while中多出判断子进程状态并如果有死亡子进程则重新调起![在这里插入图片描述](https://img-blog.csdnimg.cn/b555fb625786447c9fa1f2c857d0eecc.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAencxOTk2,size_20,color_FFFFFF,t_70,g_se,x_16)



main.py文件

This is a sample Python script.

import os
import time
import multiprocessing
from DllScoketClass import DllScoketClass #从DllClass.py中导入MyClass类

if name == ‘main’:
c1 = DllScoketClass(“soc”, “c1”, 0, 0)
c2 = DllScoketClass(“soc2”, “c2”, 0, 0)
print(“父类方法: %i” % c1.getState())
ProcessJob = []
qGet = multiprocessing.Queue()
qSen = multiprocessing.Queue()
p = multiprocessing.Process(target=c1.pocD, args=(qGet, qSen, ))
ProcessJob.append§
p.start() # 启动进程
p = multiprocessing.Process(target=c2.pocD, args=(qGet, qSen,))
ProcessJob.append§
p.start() # 启动进程

count = 0
while 1:
    if qSen.qsize() > 0:    #防止get阻塞进程
        str = qSen.get()
        print("qSen : %s" % str)
    if count == 10:
        qGet.put(1)
    count += 1
    time.sleep(1)
    nums = 0
    while nums < len(ProcessJob):       #循环遍历所有子进程判断其状态,如果死亡则重新调起
        if ProcessJob[nums].is\_alive() == False:  # 如果进程状态死亡那么则重新启动
            ProcessJob[nums].terminate()    #杀死进程
            ProcessJob[nums].join(0.1)      #回收
            print(ProcessJob)
            ProcessJob.remove(ProcessJob[nums])
            print(ProcessJob)
            p = multiprocessing.Process(target=c1.pocD, args=(qGet, qSen,))     #重新创建
            count = 0
            ProcessJob.append(p)
            p.start()       #调起
            print(ProcessJob)
        nums+=1
end

### 7、在Cdll和python中传入传出字符串使用ctypes


![在这里插入图片描述](https://img-blog.csdnimg.cn/615d6035a4a0452d8af763e100daccf9.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAencxOTk2,size_20,color_FFFFFF,t_70,g_se,x_16)  
 python代码



import multiprocessing
from multiprocessing import Process,Queue
import os
from ctypes import *
import time

pDll = CDLL(“./pythonTestCDll.dll”)

def testDLL():
pstr = create_string_buffer(1024, ‘\0’) # 创建字符串缓冲区
# 对输入输出参数进行声明
GetAndSetString = pDll.GetAndSetString
GetAndSetString.restype = c_char_p
GetAndSetString.argtypes = [c_char_p]
pchar = GetAndSetString(pstr)
szbuffer = c_char_p(pchar) # 强制转换为c_char_p类型,取其value值
print(pstr.value)
print(szbuffer.value)

if name == ‘main’:
testDLL()


C++代码



.h文件
extern “C” __declspec(dllexport) char* GetAndSetString(char*);
.cpp文件
char* GetAndSetString(char* s)
{
strcpy(s, “CDLL”);
char * greeting = “Cdll String”;
cout << “C DLL cout :” << s << endl;
return greeting;
}


### 8、在Cdll和python相互间json字符串的相关操作


纯python内部json与python对象的转换



import json

Python 字典类型转换为 JSON 对象

data1 = {
‘no’: 1,
‘name’: ‘Runoob’,
‘url’: ‘http://www.runoob.com’
}

json_str = json.dumps(data1)
print(“Python 原始数据:”, repr(data1))
print(“JSON 对象:”, json_str)

将 JSON 对象转换为 Python 字典

data2 = json.loads(json_str)
print("data2[‘name’]: ", data2[‘name’])
print("data2[‘url’]: ", data2[‘url’])


![在这里插入图片描述](https://img-blog.csdnimg.cn/ee76d4f33b724219ab38e0a25ad745cb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAencxOTk2,size_20,color_FFFFFF,t_70,g_se,x_16)  
 python代码



from ctypes import *
import time
import json

#在Cdll和python中实现字符串传替
if name == ‘main’:
pDll = CDLL(“./pythonTestCDll.dll”) #加载dll库

data1 = {
    'no': 1,
    'name': 'Runoob',
    'url': 'http://www.runoob.com'
}
data1['id'] = 12312 #添加一组元素
json_str = json.dumps(data1)    #将python对象转换为json字符串传递到C端
pstr = create\_string\_buffer(bytes(json_str, encoding='utf8'))  # 创建字符串缓冲区
#对输入输出参数进行声明
GetJson = pDll.GetJson
GetJson.restype = c_char_p
GetJson.argtypes = [c\_char\_p]
pchar = GetJson(pstr)
szbuffer = c\_char\_p(pchar)#强制转换为c_char_p类型,取其value值
print(pstr.value)
print(szbuffer.value)
data2 = json.loads(szbuffer.value) #将Cdll返回的json格式字符串进行转换为python对象
print("data2['name']: ", data2['name'])
print("data2['no']: ", data2['no'])
print("data2['url']: ", data2['url'])

C++代码  
 需引入json的第三方库,配置头文件和lib文件即可



.h文件
extern “C” __declspec(dllexport) char* GetJson(const char *s);
.cpp文件
#include “pythonTestCDll.h”
#include
#include
#include
#include “json/json.h”
using namespace std;
char * GetJson(const char *s)
{
//char* greeting = (char*)malloc(100);
//strcpy(s, “afadsfads”);
char * greeting = “{“no”: 1, “name”: “Runoob”, “url”: “http://www.runoob.com”}”;
cout << “C DLL cout :”<< s << endl;

Json::Reader reader;
Json::Value root;
if (reader.parse(s, root))  // reader将Json字符串解析到root,root将包含Json里所有子元素 
{
	std::string upload_id = root["name"].asString();  // 访问节点,
	int code = root["no"].asInt();    // 访问节点,
	cout << "CDLL cout root[name]:" << upload_id << endl;
	cout << "CDLL cout root[no]:" << code << endl;
}

return greeting;

}


### 9、python打包exe,注意multiprocessing打包的坑


![在这里插入图片描述](https://img-blog.csdnimg.cn/7de648e0494d448abd5a7190502247a7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAencxOTk2,size_20,color_FFFFFF,t_70,g_se,x_16)


打包命令



> 
> pip3 install pyinstaller  
>  pyinstaller -F main.py DllClass.py DllScoketClass.py  


![img](https://img-blog.csdnimg.cn/img_convert/822504f20b77f4c40b955edb9cb29c01.png)
![img](https://img-blog.csdnimg.cn/img_convert/dd73ac5672b82a9df6bb265fa51c096b.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

ze_20,color_FFFFFF,t_70,g_se,x_16)


打包命令



> 
> pip3 install pyinstaller  
>  pyinstaller -F main.py DllClass.py DllScoketClass.py  


[外链图片转存中...(img-HYwKw5Xw-1715661685505)]
[外链图片转存中...(img-ffLvqIXS-1715661685505)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

  • 27
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值