美文网首页C++vulkan和opengl
QT按钮socket远程控制opengl模型(4)--Apple

QT按钮socket远程控制opengl模型(4)--Apple

作者: applecai | 来源:发表于2020-03-12 20:16 被阅读0次

    QT按钮socket远程控制opengl模型(3)验证功能通过后,
    Linux Server端采用进程IPC通信
    。子进程为opengl的显示。比起多线程,多进程需要处理下进程同步关闭及僵尸进程。代码工程依然更新到我的码云

    一,进程设计

    进程IPC通信.png

    二,遇到的问题

    1.vscode无法调试多进程

    解决方案:
    launch.json添加:
    "setupCommands": [
    {"text": "-gdb-set follow-fork-mode child"}
    ]

    2.linux消息队列msgrcv收不到消息的问题

    解决方案:没有用man来仔细看msgrcv的函数,网上直接搜索了下,就找到了答案。msgrcv的第一个对象需要使用long,之前32位机上我用int测试通过,现在机器为64bit系统,所以long和int的字节数量就不是4字节了,64bit机器的long为8个字节,所以msgrcv一直无法接收到数据。修改传入参数的结构第一个对象为long型,验证通过。

    2.比起多线程,需要关注同步2个进程的退出

    由于Linux Server端窗口关闭后,主进程socket依然在和win10的client通信。所以opengl窗口关闭后,需要让server进程也关闭。
    查了资料,其实进程间算是平等的。
    僵尸进程就是指:一个进程执行了exit系统调用退出,而其父进程并没有为它收尸(调用wait或waitpid来获得它的结束状态)的进程。
    任何一个子进程(init除外)在exit后并非马上就消失,而是留下一个称外僵尸进程的数据结构,等待父进程处理。这是每个子进程都必需经历的阶段。另外子进程退出的时候会向其父进程发送一个SIGCHLD信号。

    进程间保活方案可以通过消息互发,若检测到子进程不发消息给父进程,则可以关闭子进程,再关闭父进程。
    解决方案:由于我是socket读写,有阻塞,所以我通过在SIGCHLD通知函数中直接调用exit(0)进行强制退出。

    三,main.cpp代码

    #include "socket.h"
    #include "showgl.h"
    #include "ipc.h"
    
    void handler(int sig)
    {
        pid_t pid;
        while((pid=waitpid(-1,NULL,WNOHANG))>0)
        {
            printf("wait child is sucessful\n");
            exit(0); //kill father pid
        }
        printf("child is quit\n");
    }
    
    int main(int argc, char **argv)
    {
        int ret = E_NOK;
        int keydata = 0;
        signal(SIGCHLD,handler);
        /* server operations */
        baseServer *pServer = new baseServer();
        pServer->socketCreate(AF_INET, SOCKET_TYPE, INADDR_ANY, PORT_ID, baseSocket::E_SERVER);
        pServer->socketBind();
        pServer->socketListen(2);
        MYmsg * pMymsg = new MYmsg();
        pMymsg->CreateMsg();
        /* task process */
        ServerHandler *pServerTask = new ServerHandler(pMymsg);
        /* create task for socket to send heartbeat */
        std::thread taskSendHeart(&ServerHandler::sendHeart, pServerTask, pServer);
    
        
    /* create task for opengl to display 3D */
    #if (USEFORK == true)
        pid_t id = fork();
        std::cout << "pid=" << id << std::endl;
    
        if (id < 0)
        {
            std::cout << "fork error" << std::endl;
            exit(0);
        }
        else if (id == 0) //child read
        {
            ShowOpengl *pShowTask = new ShowOpengl();
            pShowTask->glHandler(pMymsg);
            delete pShowTask;
            exit(0);
        }
        else
    #else
        ShowOpengl *pShowTask = new ShowOpengl();
        std::thread taskOpengl(&ShowOpengl::glHandler, pShowTask, pServerTask);
    #endif
        {//father
            std::cout << "start server\n"; // for debug code
            while (1)
            {
                /* wait client signal to connect */
                ret = pServer->socketAccept();
                std::cout << "h\n"; // for debug code
    
                /* create task for socket to receive key command */
                std::thread taskRec(&ServerHandler::readinfo, pServerTask, pServer);
                taskRec.detach();
    
                if (ret == E_OK)
                {
                    std::cout << "connect success" << std::endl;
                }
            }
        }
        /* close socket */
        pServer->socketDisconnect(pServer->getConnectfd());
        taskSendHeart.join();
    #if (USEFORK == true)
    #else
        taskOpengl.join();
        delete pShowTask;
    #endif
        delete pServerTask;
        delete pServer;
        pMymsg->delMsg();
        delete pMymsg;
    }
    

    相关文章

      网友评论

        本文标题:QT按钮socket远程控制opengl模型(4)--Apple

        本文链接:https://www.haomeiwen.com/subject/yuywjhtx.html