Qt C++调用Python,解决线程问题,以及GIL锁的处理

multithreading.h头文件:

#ifndef MULTITHREADING_H
#define MULTITHREADING_H

#include <math.h>
#include <Python.h>
#include <string>
#include <iostream>
#include <QString>
using namespace std;

extern QString SessId;
extern QString Permission;
extern int SearchWidgetState;

class MyThreadStateLockCls
{
public:
    MyThreadStateLockCls(void){state = PyGILState_Ensure();}
    ~MyThreadStateLockCls(void){PyGILState_Release(state);}
private:
    PyGILState_STATE state;
};
QString MyCallPyFun(string fileName,string functionName,PyObject* inputTuple);
QString get_journal(QString sess_id, int jour_id=-1, QString name="",
                    QString issn="", QString isbn="", QString post="",
                    QString host="", QString addr="", int freq=-1,
                    QString lang="", QString hist="", QString used="");
QString sign_up(QString username, QString nickname, QString password, QString forename="",QString lastname="", QString mailAddr="", QString phoneNum="");


#endif // MULTITHREADING_H

multithreading.cpp源文件

#include <multithreading.h>

QString SessId = "";
QString Permission = "";
int SearchWidgetState = -1;

QString MyCallPyFun(string fileName,string functionName,PyObject* inputTuple)
{
    PyEval_InitThreads();
    PyEval_ReleaseThread(PyThreadState_Get());
    PyObject* outputTuple;
    {
        class MyThreadStateLockCls myLock;//获取全局锁
        // 调用python的API函数处理
        PyObject *pModule = PyImport_ImportModule(fileName.data());
        if (!pModule){
            PyGILState_Ensure();
            cout<<"Can not import python module file"<<endl;
            return 0;
        }
        PyObject *pFun = PyObject_GetAttrString(pModule,functionName.data());
        if (!pFun){
            PyGILState_Ensure();
            cout<<"Can not get python function"<<endl;
            return 0;
        }
        outputTuple = PyObject_CallObject(pFun,inputTuple);
        if(!outputTuple){
            PyGILState_Ensure();
            cout<<"The called function returns NULL"<<endl;
            return 0;
        }
        else {
            cout<<"Called function completed"<<endl;
        }
    }
    PyGILState_Ensure();
    char *charStr;
    PyArg_ParseTuple(outputTuple, "s", &charStr);
    QString output = charStr;
    return output;
}
QString get_journal(QString sess_id, int jour_id, QString name,
                    QString issn, QString isbn, QString post,
                    QString host, QString addr, int freq, QString lang,
                    QString hist, QString used){
    string file = "Program";
    string fun = "get_journal";
    PyObject *input = PyTuple_New(12);
    PyTuple_SetItem(input, 0, Py_BuildValue("s",sess_id.toStdString().data()));

    if(jour_id==-1)PyTuple_SetItem(input, 1, Py_BuildValue(""));
    else PyTuple_SetItem(input, 1, Py_BuildValue("i",jour_id));

    if(name=="")PyTuple_SetItem(input, 2, Py_BuildValue(""));
    else PyTuple_SetItem(input, 2, Py_BuildValue("s",name.toStdString().data()));

    if(issn=="")PyTuple_SetItem(input, 3, Py_BuildValue(""));
    else PyTuple_SetItem(input, 3, Py_BuildValue("s",issn.toStdString().data()));

    if(isbn=="")PyTuple_SetItem(input, 4, Py_BuildValue(""));
    else PyTuple_SetItem(input, 4, Py_BuildValue("s",isbn.toStdString().data()));

    if(post=="")PyTuple_SetItem(input, 5, Py_BuildValue(""));
    else PyTuple_SetItem(input, 5, Py_BuildValue("s",post.toStdString().data()));

    if(host=="")PyTuple_SetItem(input, 6, Py_BuildValue(""));
    else PyTuple_SetItem(input, 6, Py_BuildValue("s",host.toStdString().data()));

    if(addr=="")PyTuple_SetItem(input, 7, Py_BuildValue(""));
    else PyTuple_SetItem(input, 7, Py_BuildValue("s",addr.toStdString().data()));

    if(freq==-1)PyTuple_SetItem(input, 8, Py_BuildValue(""));
    else PyTuple_SetItem(input, 8, Py_BuildValue("i",freq));

    if(lang=="")PyTuple_SetItem(input, 9, Py_BuildValue(""));
    else PyTuple_SetItem(input, 9, Py_BuildValue("s",lang.toStdString().data()));

    if(hist=="")PyTuple_SetItem(input, 10, Py_BuildValue(""));
    else PyTuple_SetItem(input, 10, Py_BuildValue("s",hist.toStdString().data()));

    if(used=="")PyTuple_SetItem(input, 11, Py_BuildValue(""));
    else PyTuple_SetItem(input, 11, Py_BuildValue("s",used.toStdString().data()));
    return MyCallPyFun(file,fun,input);
}

QString sign_up(QString username, QString nickname, QString password, QString forename,
                QString lastname, QString mailAddr, QString phoneNum){
    string file = "Program";
    string fun = "sign_up";
    PyObject *input = PyTuple_New(7);

    PyTuple_SetItem(input, 0, Py_BuildValue("s",username.toStdString().data()));
    PyTuple_SetItem(input, 1, Py_BuildValue("s",nickname.toStdString().data()));
    PyTuple_SetItem(input, 2, Py_BuildValue("s",password.toStdString().data()));

    if(forename=="")PyTuple_SetItem(input, 3, Py_BuildValue(""));
    else PyTuple_SetItem(input, 3, Py_BuildValue("s",forename.toStdString().data()));

    if(lastname=="")PyTuple_SetItem(input, 4, Py_BuildValue(""));
    else PyTuple_SetItem(input, 4, Py_BuildValue("s",lastname.toStdString().data()));

    if(mailAddr=="")PyTuple_SetItem(input, 5, Py_BuildValue(""));
    else PyTuple_SetItem(input, 5, Py_BuildValue("s",mailAddr.toStdString().data()));

    if(phoneNum=="")PyTuple_SetItem(input, 6, Py_BuildValue(""));
    else PyTuple_SetItem(input, 6, Py_BuildValue("s",phoneNum.toStdString().data()));

    return MyCallPyFun(file,fun,input);
}

调用举例:

QString QStrSignUp = sign_up(ui->LineAccountName->text(),ui->LineNickname->text(),ui->LinePassword->text(),ui->LineFirstName->text(),ui->LineLastName->text(),ui->LineEmail->text(),ui->LineTel->text());
//qDebug()<<QStrSignUp;
QString JudgeNickname = QStrSignUp.section(";",0,0);
if(JudgeNickname == "409"){
    ui->Text2->setFont(font);
    ui->Text2->setText("用户名或昵\n称已被注册");
    ui->Text2->show();
    ui->Text1->setFont(font);
    ui->Text1->setText("用户名或昵\n称已被注册");
    ui->Text1->show();
}

Program.py

from urllib import request
import json
from datetime import datetime, timedelta
from json import JSONEncoder
import socket
socket.setdefaulttimeout(1)


class DatetimeEncoder(JSONEncoder):
    """Help to jsonify the datetime.
    Still need to loads it manually."""
    def default(self, o):
        if isinstance(o, datetime):
            return o.timestamp()
        return super().default(0)

def json_rpc(method, params, id=0, jsonrpc='2.0', url='http://127.0.0.1/'):
        try:
                headers = {'Content-Type': 'application/json'}
                data = {'method': method, 'params': params, 'id': id, 'jsonrpc': jsonrpc}
                #r = requests.post(url, json=data, headers=headers)
                data = json.dumps(data,cls = DatetimeEncoder).encode('utf-8')
                req = request.Request(url, data=data, headers=headers)
                r = request.urlopen(req)
                assert r.getcode()==200
                text = r.read().decode('utf-8')
                return json.loads(text)
        except Exception:
                return {'error': {'code': 404, 'message': 'Failed to request'}}

def restart_world():
        resp = json_rpc('restart_world', [])

#强烈推荐注册管理员,5元包月
def admin_sign_up(username, nickname, password, forename=None, lastname=None, mailAddr=None, phoneNum=None):
        resp = json_rpc('admin_sign_up', [username, nickname, password, forename, lastname, mailAddr, phoneNum])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+resp['result'],

def sign_up(username, nickname, password, forename=None, lastname=None, mailAddr=None, phoneNum=None):
        resp = json_rpc('sign_up', [username, nickname, password, forename, lastname, mailAddr, phoneNum])
        if 'error' in resp: #出错
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+resp['result'], #未出错,返回str类型的id

def sign_in(username, password):
        resp = json_rpc('sign_in', [username, password])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+resp['result'],#返回str类型的id

def sign_out(sess_id):
        resp = json_rpc('sign_out', [sess_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def get_user(sess_id):
        resp = json_rpc('get_user', [sess_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        t=[str(x) for x in resp['result'].values()]
        t = ','.join(t)
        return '0;'+t,#返回元组,包含该用户的所有信息

def get_user_advanced(sess_id,user_id = None,username=None,nickname=None,forename=None,lastname=None,mailaddr=None,phonenum=None):
        resp = json_rpc('get_user_advanced', [sess_id,user_id, username,nickname,forename,lastname,mailaddr,phonenum])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                t = [str(x) for x in i.values()]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        #'{0};{1};{2}'.format(0,len(),a)
        return '0;'+str(len(resp['result']))+';'+a,#返回期刊元组的列表

def set_user(sess_id, nickname=None, password=None, forename=None, lastname=None, mailAddr=None, phoneNum=None):
        resp = json_rpc('set_user', [sess_id, nickname, password, forename, lastname, mailAddr, phoneNum])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def del_user(sess_id):
        resp = json_rpc('del_user', [sess_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def add_journal(sess_id, name, issn, isbn, post, host, addr, freq, lang, hist=None, used=None):
        if hist is not None:
                if not hist.isdigit():
                        hist=None
                else:
                        hist=int(hist)
        resp = json_rpc('add_journal', [sess_id, name, issn, isbn, post, host, addr, freq, lang, hist, used])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回int类型期刊id

def get_journal(sess_id, jour_id=None, name=None, issn=None, isbn=None, post=None, host=None, addr=None, freq=None, lang=None, hist=None, used=None):
        if hist is not None:
                if not hist.isdigit():
                        hist=None
                else:
                        hist=int(hist)
        resp = json_rpc('get_journal_advanced', [sess_id, jour_id, name, issn, isbn, post, host, addr, freq, lang, hist, used])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                t = [str(x) for x in i.values()]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        #'{0};{1};{2}'.format(0,len(),a)
        return '0;'+str(len(resp['result']))+';'+a,#返回期刊元组的列表

def get_journal_reverse(sess_id, subs_id, sto_id, bor_id):
        resp = json_rpc('get_journal_reverse', [sess_id, subs_id, sto_id, bor_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        t=[str(x) for x in resp['result'].values()]
        t = ','.join(t)
        return '0;'+t,

def set_journal(sess_id, jour_id, name=None, issn=None, isbn=None, post=None, host=None, addr=None, freq=None, lang=None, hist=None, used=None):
        if hist is not None:
                if not hist.isdigit():
                        hist=None
                else:
                        hist=int(hist)
        resp = json_rpc('set_journal', [sess_id, jour_id, name, issn, isbn, post, host, addr, freq, lang, hist, used])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def del_journal(sess_id, jour_id):
        resp = json_rpc('del_journal', [sess_id, jour_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def add_subscribe(sess_id, year, jour_id):
        resp = json_rpc('add_subscribe', [sess_id, year, jour_id])#int year
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回int类型的subs_id

def get_subscribe(sess_id, subs_id=None, year=None, jour_id=None):
        resp = json_rpc('get_subscribe', [sess_id, subs_id, year, jour_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                t = [str(x) for x in i.values()]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        return '{0};{1};{2}'.format(0,len(resp['result']),a),#返回征订项元组的列表

def chaifen_jour(obj):
        t=[str(x) for x in obj['journal'].values()]
        t = ','.join(t)
        obj['journal'] = t

def get_subscribe_full(sess_id, subs_id=None, year=None, jour_id=None):
        resp = json_rpc('get_subscribe_full', [sess_id, subs_id, year, jour_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                chaifen_jour(i)
                t = [str(x) for x in i.values()]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        return '{0};{1};{2}'.format(0,len(resp['result']),a),

def set_subscribe(sess_id, subs_id, year=None, jour_id=None):
        resp = json_rpc('set_subscribe', [sess_id, subs_id, year, jour_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def del_subscribe(sess_id, subs_id):
        resp = json_rpc('del_subscribe', [sess_id, subs_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def add_storage(sess_id, vol, num, subs_id):
        resp = json_rpc('add_storage', [sess_id, vol, num, subs_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回int类型sto_id

def get_storage(sess_id, sto_id=None, vol=None, num=None, subs_id=None,):
        resp = json_rpc('get_storage', [sess_id, sto_id, vol, num, subs_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                t = [str(x) for x in i.values()]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        return '0;'+str(len(resp['result']))+';'+a,#返回存储项元组的列表

def chaifen_stor(obj):
        inobj = obj['subscribe']
        t=[str(x) for x in inobj['journal'].values()]
        t = ','.join(t)
        inobj['journal'] = t
        v=[str(x) for x in obj['subscribe'].values()]
        v = ','.join(v)
        obj['subscribe'] = v

def get_storage_full(sess_id, sto_id=None, vol=None, num=None, sub_id=None):
        resp = json_rpc('get_storage_full', [sess_id, sto_id, vol, num, sub_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                chaifen_stor(i)
                t = [str(x) for x in i.values()]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        return '{0};{1};{2}'.format(0,len(resp['result']),a),

def set_storage(sess_id, sto_id, vol=None, num=None, subs_id=None,):
        resp = json_rpc('set_storage', [sess_id, sto_id, vol, num, subs_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def del_storage(sess_id, sto_id):
        resp = json_rpc('del_storage', [sess_id, sto_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def add_article(sess_id, title, author, pageNum, sto_id, k1=None, k2=None, k3=None, k4=None, k5=None):
        resp = json_rpc('add_article', [sess_id, title, author, pageNum, sto_id, k1, k2, k3, k4, k5])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回int类型的art_id

def get_article(sess_id, art_id=None, title=None, author=None, pageNum=None, sto_id=None, k1=None, k2=None, k3=None, k4=None, k5=None):
        resp = json_rpc('get_article', [sess_id, art_id, title, author, pageNum, sto_id, k1, k2, k3, k4, k5])
        if 'error' in resp:
                #return '1,'+'0,'+str(resp['error']['code']),str(resp['error']['message']),
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                t = [str(x) for x in i.values()]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        return '0;'+str(len(resp['result']))+';'+a,#返回文章项元组的列表

def get_article_advanced(sess_id, art_id=None, title=None, author=None, pageNum=None, sto_id=None, keywords=None):
        resp = json_rpc('get_article_advanced', [sess_id, art_id, title, author, pageNum, sto_id, keywords])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                t = [str(x) for x in i.values()]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        return '0;'+str(len(resp['result']))+';'+a,#返回文章项元组的列表

def set_article(sess_id, art_id, title=None, author=None, pageNum=None, sto_id=None, k1=None, k2=None, k3=None, k4=None, k5=None):
        resp = json_rpc('set_article', [sess_id, art_id, title, author, pageNum, sto_id, k1, k2, k3, k4, k5])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def del_article(sess_id, art_id):
        resp = json_rpc('del_article', [sess_id, art_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def add_borrow(sess_id, user, sto_id, bt_year=None,bt_month=None,bt_day=None,at_year=None,at_month=None,at_day=None):
        bt = datetime(year=bt_year,month=bt_month,day=bt_day)
        at = datetime(year=at_year,month=at_month,day=at_day)
        rt=None
        resp = json_rpc('add_borrow', [sess_id, user, sto_id, bt, at, rt])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回int类型的bor_id

def checknone_fts(ob):
        if ob is None:
                return None
        t = datetime.fromtimestamp(ob)
        return '{},{},{},{},{},{}'.format(t.year,t.month,t.day,t.hour,t.minute,t.second)
        #return ','.join(t.year,t.month,t.day,t.hour,t.minute,t.second)
        #return datetime.fromtimestamp(ob)

def get_borrow(sess_id, bor_id=None, user_id=None,sto_id=None, bt=None, at=None, rt=None):
        resp = json_rpc('get_borrow', [sess_id, bor_id,user_id, sto_id, bt, at, rt])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                #i['borrowtime'] = datetime.fromtimestamp(i['borrowtime'])
                #i['agreedtime'] = datetime.fromtimestamp(i['agreedtime'])
                #i['returntime'] = datetime.fromtimestamp(i['returntime'])
                i['borrowtime'] = checknone_fts(i['borrowtime'])
                i['agreedtime'] = checknone_fts(i['agreedtime'])
                i['returntime'] = checknone_fts(i['returntime'])
                t = [str(x) for x in i.values()]
                t = t[0:1]+t[4:]+t[1:4]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        return '0;'+str(len(resp['result']))+';'+a,#返回借阅项元组的列表

def chaifen_bor(obj):
        t=[str(x) for x in obj['user'].values()]
        t = ','.join(t)
        obj['user'] = t
        inobj = obj['storage']['subscribe']
        r=[str(x) for x in inobj['journal'].values()]
        r = ','.join(r)
        inobj['journal'] = r
        v=[str(x) for x in obj['storage']['subscribe'].values()]
        v = ','.join(v)
        obj['storage']['subscribe'] = v
        g = [str(x) for x in obj['storage'].values()]
        g = ','.join(g)
        obj['storage'] = g

def get_borrow_full(sess_id, bor_id=None, user_id=None,sto_id=None, bt=None, at=None, rt=None):
        resp = json_rpc('get_borrow_full', [sess_id, bor_id, user_id, sto_id, bt, at, rt])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        a = []
        for i in resp['result']:
                #i['borrowtime'] = datetime.fromtimestamp(i['borrowtime'])
                #i['agreedtime'] = datetime.fromtimestamp(i['agreedtime'])
                #i['returntime'] = datetime.fromtimestamp(i['returntime'])
                i['borrowtime'] = checknone_fts(i['borrowtime'])
                i['agreedtime'] = checknone_fts(i['agreedtime'])
                i['returntime'] = checknone_fts(i['returntime'])
                chaifen_bor(i)
                t = [str(x) for x in i.values()]
                t=t[0:1]+t[4:]+t[1:4]
                obj = ','.join(t)
                a.append(obj)
        a = ';'.join(a)
        return '0;'+str(len(resp['result']))+';'+a,

def set_borrow(sess_id, bor_id=None, user=None, sto_id=None, bt=None, at=None, rt=None):
        resp = json_rpc('set_borrow', [sess_id, bor_id, user, sto_id, bt, at, rt])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def end_borrow(sess_id, bor_id):
        resp = json_rpc('end_borrow', [sess_id, bor_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

def new_datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0):#all int
        return datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second, microsecond=microsecond)

#这个貌似没用了
def get_datetime(dt):
        dt.timetuple()
        t = [str(x) for x in dt.values()]
        obj = ','.join(t)
        return t

def del_borrow(sess_id, bor_id):
        resp = json_rpc('del_borrow', [sess_id, bor_id])
        if 'error' in resp:
                return str(resp['error']['code'])+';'+str(resp['error']['message']),
        return '0;'+str(resp['result']),#返回None

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果要在 Go 调用 Python 代码,且只能使用协程并发执行,可以使用 `go-python` 这个第三方库来解决 GIL 问题。 `go-python` 库是一个 Go 语言和 Python 语言之间的桥梁,它可以在 Go 执行 Python 代码,并且可以通过 Go 协程并发执行 Python 代码,从而避开 GIL 的限制。 具体的步骤如下: 1. 安装 `go-python` 库,可以使用 `go get` 命令进行安装:`go get github.com/sbinet/go-python` 2. 在 Go 代码导入 `go-python` 包。 3. 初始化 Python 解释器,可以使用 `go-python` 包的 `Initialize()` 函数进行初始化。 4. 创建一个 Python 模块对象,可以使用 `go-python` 包的 `NewModule()` 函数进行创建。 5. 将 Python 代码加载到模块对象,可以使用 `go-python` 包的 `AddCode()` 函数将 Python 代码添加到模块对象。 6. 调用 Python 函数,可以使用 `go-python` 包的 `Py.Run()` 函数来执行 Python 函数。 7. 可以使用 Go 协程并发执行 Python 代码,从而避开 GIL 的限制。 下面是一个简单的示例代码: ```go package main import ( "fmt" "github.com/sbinet/go-python" ) func main() { // 初始化 Python 解释器 python.Initialize() // 创建一个 Python 模块对象 module := python.NewModule("mymodule") // 将 Python 代码添加到模块对象 err := python.AddCode(` def do_something(): # 在 Python 执行一些任务,比如计算斐波那契数列 a, b = 0, 1 while True: yield a a, b = b, a + b `, module) if err != nil { fmt.Println("添加 Python 代码出错:", err) return } // 在 Go 协程调用 Python 函数 for i := 0; i < 10; i++ { go func() { // 调用 Python 函数 result, err := python.Py.RunString("mymodule.do_something()", python.FileInput, module.Dict()) if err != nil { fmt.Println("调用 Python 函数出错:", err) return } // 输出结果 fmt.Println(result) }() } // 等待协程执行完成 select {} } ``` 在上面的示例,我们使用 `go-python` 包初始化了 Python 解释器,并创建了一个名为 `mymodule` 的 Python 模块对象。然后将计算斐波那契数列的 Python 代码添加到模块对象。在 Go 协程调用 Python 函数 `do_something()`,使用协程并发执行 Python 代码,从而避开 GIL 的限制。 需要注意的是,使用 `go-python` 包在 Go 调用 Python 代码需要注意一些细节,比如需要手动进行 Python 对象的引用计数管理,避免内存泄漏等问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值