分布式计算框架(五) 计算模块与动态链接库模板

五、计算模块与动态链接库模板

    5.1、 计算模块结构

    计算模块主要负责任务的计算,根据任务的信息动态调用相应的动态链接库以及函数,计算完毕后传输计算结果,计算模块类关系表如下:

 

类名

关系类

    关系

Handle_module

Setting

聚合

Handle_module

local_socket

聚合

Handle_module

c_Template

聚合

计算模块结构类图如下:

  分布式计算框架(五) 计算模块与动态链接库模板_第1张图片

5.2 计算模块基本原理

     5.2.1 任务队列

       为了提高计算任务处理效率,通常保证一个计算节点拥有多个任务,任务计算完毕后能够立即计算而不用等待服务器发送新任务。基本思路就是建立一个任务队列,当新任务传输进来放进队列,处理玩任务后从队列中提取任务,对应代码如下:

void Handle_module::add_UnhandleTask(QString id, QString type, QString data)
{
    UnHandleTask Task={id,type,data};
    UnHandleTaskList.append(Task);
}
void Handle_module::handle_UnhandleTask()
{
    if(UnHandleTaskList.isEmpty())
    {
        return;
    }

    QSharedPointer freeTemplate=getFreeTemplate();
    if(!freeTemplate.isNull())
    {
        template_Type[freeTemplate.data()]=caculating_status;
        UnHandleTask Task= UnHandleTaskList.first();
        emit send_instruction(QstringTotype(Task.type),Task.data,freeTemplate.data());
        UnHandleTaskList.removeFirst();
        handle_UnhandleTask();
    }
}

    5.2.2 调用DLL  

    在实际测试时发现有极小概率发生DLL调用失败,由于采用动态调用不可能调用一次读取一次DLL,并且本框架分配任务思路为一个一个任务按顺序分配,因此同一时间处理的任务是相同的。所以在对应类中声明QLibrary lib类,这样能提高效率降低出错率,以Handle函数为例代码如下:

void     c_Template::handledata(QString data)
{
    QString send_data;                              //开始调用handle函数
    QStringList receivedata=data.split("**&&##");
    if(receivedata.size()!=4)
    {
        c_send("",readfail,"");

        return;
    }

    QString taskid=receivedata[0];
    QString taskbelongid=receivedata[2];
    QString dll_Name=receivedata[1];
    QString taskdata=receivedata[3];
    typedef QString(*FUN1)(QString);
    QString file_path=QCoreApplication::applicationDirPath()+"\\"+"DLL"+"\\"+dll_Name;
    int frequency=0;
    if(LastLoadDll!=file_path)
    {
        lib.unload();
        LastLoadDll=file_path;
        lib.setFileName(file_path);
        while(true)
        {
            if(lib.load())
            {
                FUN1 handle = (FUN1)lib.resolve("handle");
                LastLoadTime=QDateTime::currentDateTime();
                if(handle)
                {
                    send_data=handle(taskdata);
                    break;
                }
                else
                {
                    qDebug()<<"handle函数加载失败!";
                }

            }
            else
            {
                qDebug()<<"DLL加载失败!";
            }
            frequency++;
            if(frequency>100)
            {

                QStringList senddata;
                senddata.append(taskbelongid);
                senddata.append(send_data);
                QString   senddata1=senddata.join("@@@");
                c_send(taskid,loadfail,senddata1);
                return;
            }
        }
    }
    else
    {
        FUN1 handle = (FUN1)lib.resolve("handle");
        if(handle)
        {
            send_data=handle(taskdata);
        }
        else
        {
            QStringList senddata;
            senddata.append(taskbelongid);
            senddata.append(send_data);
            QString   senddata1=senddata.join("@@@");
            c_send(taskid,loadfail,senddata1);
            qDebug()<<"handle函数加载失败!";
            return;
        }
    }
    QStringList senddata;
    senddata.append(taskbelongid);
    senddata.append(send_data);
    QString   senddata1=senddata.join("@@@");
    c_send(taskid,handle,senddata1);
}

在多次调用失败后将发送失败消息给计算节点。

 5.2.3  计算模块小结

    DLL调用、任务队列、DLL调用错误处理等需要仔细思考。

5.3 动态库模板

为了方便用户编程,因此提供固定动态库模板,用户在此编程生成DLL用来计算问题。

以N皇后算法为模板,对应代码如下:

QStringList read(QString data)
{
   QStringList receive=data.split(",");
   if(receive.size()<2)
   {
       return QStringList();
   }
   int num=receive[0].toInt();
   int problem_size=receive[1].toInt();

   queen_decomposition f(num,problem_size);
   QList data1;
   data1=f.decomposition_problem();
   QStringList  result;
   for(int a=0;a init_data;
    for(int b=0;b

到此为止大部分都介绍完毕,耗时8个月迭代几个版本,一个字爽。。

你可能感兴趣的:(QT,c++,分布式)