目录

Function Flow Runtime Concurrent Queue (C++)

Overview

The FFRT concurrent queue provides the capability of setting the priority and queue concurrency. Tasks in the queue can be executed on multiple threads at the same time, achieving better effects.

Example: Bank Service System

For example, each customer (common customer or VIP customer) submits a service request to the bank service system. The service request of the VIP customer can be processed first. The bank system has two windows for handling service requests submitted by customers.

You can use the FFRT paradigm to perform the following modeling:

The implementation code is as follows:

#include <unistd.h>
#include "hilog/log.h"
#include "ffrt/ffrt.h" // From the HarmonyOS third-party library "@ppd/ffrt"

#undef LOG_TAG
#define LOG_TAG "ConcurrentCppTag"
const int SLEEP_TIME = 100 * 1000; // 100ms
const int BANK_CONCURRENCY = 2;

class BankQueueSystem {
private:
    std::unique_ptr<ffrt::queue> queue_;

public:
    BankQueueSystem(const char *name, int concurrency)
    {
        queue_ = std::make_unique<ffrt::queue>(
            ffrt::queue_concurrent, name, ffrt::queue_attr().max_concurrency(concurrency));
        OH_LOG_INFO(LOG_APP, "bank system has been initialized");
    }

    ~BankQueueSystem()
    {
        queue_ = nullptr;
        OH_LOG_INFO(LOG_APP, "bank system has been destroyed");
    }

    // Start to queue, that is, submit queue tasks.
    ffrt::task_handle Enter(const std::function<void()>& func, const char *name, ffrt_queue_priority_t level, int delay)
    {
        return queue_->submit_h(func, ffrt::task_attr().name(name).priority(level).delay(delay));
    }

    // Exit the queue, that is, cancel queue tasks.
    int Exit(const ffrt::task_handle &t)
    {
        return queue_->cancel(t);
    }

    // Wait for tasks in the queue.
    void Wait(const ffrt::task_handle& handle)
    {
        queue_->wait(handle);
    }
};

void BankBusiness()
{
    usleep(SLEEP_TIME);
    OH_LOG_INFO(LOG_APP, "saving or withdraw ordinary customer");
}

void BankBusinessVIP()
{
    usleep(SLEEP_TIME);
    OH_LOG_INFO(LOG_APP, "saving or withdraw VIP");
}

int ConcurrentQueueCppExec()
{
    BankQueueSystem bankQueue("Bank", BANK_CONCURRENCY);

    auto task1 = bankQueue.Enter(BankBusiness, "customer1", ffrt_queue_priority_low, 0);
    auto task2 = bankQueue.Enter(BankBusiness, "customer2", ffrt_queue_priority_low, 0);
    // VIP customers have the priority to enjoy services.
    auto task3 = bankQueue.Enter(BankBusinessVIP, "customer3 vip", ffrt_queue_priority_high, 0);
    auto task4 = bankQueue.Enter(BankBusiness, "customer4", ffrt_queue_priority_low, 0);
    auto task5 = bankQueue.Enter(BankBusiness, "customer5", ffrt_queue_priority_low, 0);

    // Cancel the service for customer 4.
    bankQueue.Exit(task4);

    // Wait until all customer services are complete.
    bankQueue.Wait(task5);
    return 0;
}

Available APIs

The main FFRT APIs involved in the preceding example are as follows:

Name Description
class task_attr Task attribute class.
class queue_attr Queue attribute class.
class queue Queue class.
  • For details about how to use FFRT C++ APIs, see Using FFRT C++ APIs.
  • When using FFRT C or C++ APIs, you can use the FFRT C++ API third-party library to simplify header file inclusion, that is, use the #include "ffrt/ffrt.h" header file inclusion statement.

Constraints

It is recommended that the maximum concurrency of a concurrent queue be within a proper range. If the value is too large, it is meaningless to exceed the number of Worker threads. If the value is too small, the system resource utilization may be low.