簡體   English   中英

C ++串行線程執行器

[英]C++ serial thread executor

來自Java環境(特別是Android),在不阻塞主線程的情況下在新線程中執行某些代碼從未遇到任何問題。 由於我現在必須使用C ++,因此我偶然發現了以下問題。

客戶端代碼通過JNI執行我的本機(C ++)代碼:

JNIEXPORT jbyteArray JNICALL
Java_com_native_project_NativeInterface_processData(JNIEnv *env, jobject instance, jbyteArray inputData_) {
    vector<unsigned char> inputData = jbyteArrayToBytes(env, inputData_);
    const vector<unsigned char> &result = getDataProcessor(env, instance).processData(inputData);
    return bytesTojbyteArray(env, result);
}

DataProcessor getDataProcessor(JNIEnv *env, jobject instance) {
    return DataProcessor(env, instance);
}

然后在我的DataProcessor我想做兩個嘗試:

  • 處理數據並盡快返回
  • 將數據寫入活動日志(例如數據庫)而不會延遲響應(因此,首先返回響應,然后記錄數據)

示例代碼:

class BasicAsync {
private:
    void logToDB(const vector<unsigned char> &inputData) {
        // connect to DB and write data to it
    }

    vector<unsigned char> compute(const vector<unsigned char> &inputData) {
        vector<unsigned char> result = vector<unsigned char>();
        // rocket-science computation in here
        return result;
    }

public:
    vector<unsigned char> processData(const vector<unsigned char> &inputData) {
        // perform data computation and produce output
        vector<unsigned char> result = compute(inputData);

        // create a thread that writes the data to activity log without delaying the response return
        logToDB(inputData);

        //return result while data is written to activity log
        return result;
    }
}

我的主要觀點是:

  1. 是否可以在C ++中使用(我正在使用C ++ 11)?
  2. 如果需要一段時間將數據寫入數據庫,那么在這段時間內DataProcessor對象會發生什么情況(因為在其生命周期范圍結束時,通過JNI返回響應后應該銷毀它-也許我在這里丟失了一些東西)?
  3. 是否有任何串行線程執行器,以便我可以向數據庫中寫入一些內容(它們將被放入FIFO隊列中,並在同一線程中按順序保留)?
  1. 考慮活動對象模式的一種變體,以實現一個串行執行隊列來執行您必須長時間序列化的長時間運行的工作:
#include <thread>
#include <mutex>
#include <functional>
#include <queue>

class SerialExecutionQueue
{
public:
    typedef std::function<void()>   QueueItem;

    SerialExecutionQueue() :
    m_shouldQuit(false),
    m_executor([this]()
       {
           executor();
       })
    {

    }

    void enqueueWork(QueueItem item)
    {
        {
            std::lock_guard<std::mutex> l(m_mutex);
            m_queue.push(item);
        }
        m_cv.notify_all();
    }

    void executor()
    {
        while (!m_shouldQuit)
        {
            std::unique_lock<std::mutex> lock(m_mutex);
            while (m_queue.size())
            {
                auto item = m_queue.front();
                m_queue.pop();
                m_mutex.unlock();
                item();
                m_mutex.lock();
            }
            m_cv.wait(lock);
        }
    }

private:
    bool                    m_shouldQuit;
    std::condition_variable m_cv;
    std::mutex              m_mutex;
    std::queue<QueueItem>   m_queue;
    std::thread             m_executor;
};
int main(int argc, const char * argv[])
{

    SerialExecutionQueue queue;

    queue.enqueueWork([]()
          {
              std::cout << "Did some work 1" <<std::endl;
          });


    queue.enqueueWork([]()
          {
              std::cout << "Did some work 2" <<std::endl;
          });

    sleep(1);

    queue.enqueueWork([]()
          {
              std::cout << "Did some work 3" <<std::endl;
          });

    sleep(10);
    return 0;
}

輸出:

Did some work 1
Did some work 2
Did some work 3

在2011年之前,必須直接使用本機API(例如pthreads)或部署第三方包裝器庫(如boost中的庫),但是自2011年以來,C ++提供了相當豐富的標准化線程接口。

也許您首先自己看看,嘗試一下,然后在帖子中添加更具體的問題; 然后,我將相應地擴展此答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM