C ++ - 如何恢复与提升一个线程? [英] C++ - How do I revive a thread with boost?

查看:101
本文介绍了C ++ - 如何恢复与提升一个线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

摘要:客户在一个与其他用户Teamspeak服务器。当其他用户开始讲话,这个插件运行的函数 setSpeakerPosition()用户每500毫秒,直到他们停止发言。如果他们再次开始讲应该再做一次。

问题:如果我只是做了 .reset段(新的boost ::线程(...))每次他们开始发言时间,似乎覆盖现有螺纹(如果他们之前已经使用),并导致崩溃。我相信我需要'振兴'现有的线程,或者正确杀死它。

  //创建像一个数组:speakingThreads [CLIENT_ID] =阵列(bIsSpeaking,ptrThread)
TYPEDEF提高:: shared_ptr的<提高::线程> SmartThread;
地图< anyID,对<布尔,SmartThread>> speakingThreads;//当有人开始或停止说话调用
无效ts3plugin_onTalkStatusChangeEvent(UINT64 serverConnectionHandlerID,诠释状态,INT isReceivedWhisper,anyID clientID的){    //获取我的客户ID
    anyID身份识别码;
    ts3Functions.getClientID(serverConnectionHandlerID,&安培;身份识别码);    //如果别人说话开始
    如果(clientID的=本身份识别码和放大器;!&放大器;状态== STATUS_TALKING){
        //设置客户端'说话'(允许线程循环运行)
        speakingThreads [clientID的]。首先= TRUE;        //如果这是他们所讲的第一次,启动一个线程
        如果(speakingThreads [clientID的]。第二== NULL){
            //创建线程不断更新扬声器位置,而他的讲话
            speakingThreads [clientID的] .second.reset(新的boost ::线程(speakerActiveThread,serverConnectionHandlerID,clientID的));
            _log(启动线程,0);
        }
        //或者,如果他们之前已经谈到,重振线
        其他{
            speakingThreads [clientID的] .second-> speakerActiveThread(serverConnectionHandlerID,clientID的); //错误C2039:'speakerActiveThread':不是'的boost ::线程的一员
            _log(振兴螺纹,0);
        }
    }
    //如果别人说话停止
    否则,如果(clientID的=本身份识别码和放大器;!&放大器;状态== STATUS_NOT_TALKING){
        如果(speakingThreads.find(clientID的)!= speakingThreads.end()){
            //为扬声器禁用线程循环停止更新自己的位置
            speakingThreads [clientID的]。首先= FALSE;
            _log(中断线程说起,0);
        }
    }
}//当有人开始说的线程中运行,循环,直到他们结束通话后
无效speakerActiveThread(UINT64 serverConnectionHandlerID,anyID clientID的){
    //当客户'说话'
    而(speakingThreads [clientID的]。首先){
        如果(setSpeakerPosition(serverConnectionHandlerID,clientID的)!= ERROR_OK){
            _log(ERROR设置扬声器位置,1);
        }
        _log(设置扬声器位置,0);
        睡眠(UPDATE_SPEAKER_MS); // 500
    }
}


解决方案

您不能复活的线程。你已经创建了一个线程对象,将其传递给要执行一个线程函数后,该函数在一个单独的操作系统线程运行;当函数结束 - 的线头(退出)。请注意,如果线程对象被销毁(例如,超出范围),它不会影响线程本身。

SUMMARY: Client is in Teamspeak server with other users. When other users begin speaking, this plugin runs a function setSpeakerPosition() on the user every 500ms until they stop speaking. It should do it again if they start speaking again.

PROBLEM: If I simply do a .reset(new boost::thread(...)) every time they start speaking, it seems to overwrite an existing thread (if they've spoken before) and leads to a crash. I believe I need to 'revive' an existing thread, or kill it properly.

// Create an array like: speakingThreads[client_id] = array(bIsSpeaking, ptrThread)
typedef boost::shared_ptr<boost::thread> SmartThread;
map<anyID, pair<bool, SmartThread>> speakingThreads;

// Called when someone starts or stops talking
void ts3plugin_onTalkStatusChangeEvent(uint64 serverConnectionHandlerID, int status, int isReceivedWhisper, anyID clientID) {

    // Get my client id
    anyID myID;
    ts3Functions.getClientID(serverConnectionHandlerID, &myID);

    // If someone else starts talking
    if(clientID != myID && status == STATUS_TALKING) {
        // Set client to 'is speaking' (allows thread loop to run)
        speakingThreads[clientID].first = true;

        // If this is the first time they have spoken, start a thread
        if(speakingThreads[clientID].second == NULL) {
            // Create thread to keep updating speaker position while he's speaking
            speakingThreads[clientID].second.reset(new boost::thread(speakerActiveThread, serverConnectionHandlerID, clientID));
            _log("Starting Thread", 0);
        }
        // Or if they've spoken before, revive the thread
        else {
            speakingThreads[clientID].second->speakerActiveThread(serverConnectionHandlerID, clientID); // error C2039: 'speakerActiveThread' : is not a member of 'boost::thread'
            _log("Reviving Thread", 0);
        }
    }
    // If someone else stops talking
    else if(clientID != myID && status == STATUS_NOT_TALKING) {
        if(speakingThreads.find(clientID) != speakingThreads.end()) {
            // Disable thread loop for the speaker to stop updating his position
            speakingThreads[clientID].first = false;
            _log("Interrupted Speaking Thread", 0);
        }
    }
}

// Thread run when someone starts speaking, loops until they finish speaking
void speakerActiveThread(uint64 serverConnectionHandlerID, anyID clientID) {
    // While client 'is speaking'
    while(speakingThreads[clientID].first) {
        if(setSpeakerPosition(serverConnectionHandlerID, clientID) != ERROR_ok) {
            _log("ERROR Setting Speaker Position", 1);
        }
        _log("Set Speaker Position", 0);
        Sleep(UPDATE_SPEAKER_MS); // 500
    }
}

解决方案

You can not "revive" threads. After you've created a boost::thread object, passing to it a thread function you want to execute, the function runs in a separate OS thread; when the function ends - the thread ends (exits). Note that if boost::thread object gets destroyed (eg., goes out of scope), it doesn't affect the thread itself.

这篇关于C ++ - 如何恢复与提升一个线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆