隊列優(yōu)先級和任務(wù)執(zhí)行順序的關(guān)系
實驗代碼1 :相同數(shù)量任務(wù),低優(yōu)先級隊列先提交
隊列優(yōu)先級從低到高,每個隊列入隊若干個任務(wù)(上一個隊列入隊完成后,才向下一個入隊),查看任務(wù)執(zhí)行情況
void queue_concurrent()
{
os_signpost_id_t __spid = os_signpost_id_make_with_pointer(LOG_PERF, (void*)now_ns);
os_signpost_interval_begin(LOG_PERF, __spid, "queue_concurrent", "");
auto g = dispatch_group_create();
auto q = dispatch_queue_create("q", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_USER_INTERACTIVE, 0));
auto q1 = dispatch_queue_create("q1", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_USER_INITIATED, 0));
auto q2 = dispatch_queue_create("q2", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, 0));
auto q3 = dispatch_queue_create("q3", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_UTILITY, 0));
auto q4 = dispatch_queue_create("q4", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_BACKGROUND, 0));
auto start = now_ns();
for (int i = 0; i < task_count; i++) {
dispatch_group_async_f(g, q4, nullptr, sleep_10ms);
}
for (int i = 0; i < task_count; i++) {
dispatch_group_async_f(g, q3, nullptr, sleep_11ms);
}
for (int i = 0; i < task_count; i++) {
dispatch_group_async_f(g, q2, nullptr, sleep_12ms);
}
for (int i = 0; i < task_count; i++) {
dispatch_group_async_f(g, q1, nullptr, sleep_13ms);
}
for (int i = 0; i < task_count; i++) {
dispatch_group_async_f(g, q, nullptr, sleep_14ms);
}
os_signpost_interval_end(LOG_PERF, __spid, "queue_concurrent", "");
dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
printf("total takes %llu ms\n", now_ns() - start);
}
任務(wù)提交的隊列所處的優(yōu)先級順序由低到高:
QOS_CLASS_BACKGROUND,QOS_CLASS_UTILITY,QOS_CLASS_DEFAULT,QOS_CLASS_USER_INITIATED,QOS_CLASS_USER_INTERACTIVE
圖里面的任務(wù),最下面卻先執(zhí)行完成的是高優(yōu)先級QOS_CLASS_USER_INTERACTIVE,最上面卻最后執(zhí)行完成的是低優(yōu)先級QOS_CLASS_BACKGROUND
少量任務(wù)(task_count = 50)

iPhone7,iOS 15.7

iPad mini 5,iOS 18.5

iPhone 14 Pro Max,iOS 26
大量任務(wù)(task_count = 500)

iPhone7,iOS 15.7

iPad mini 5,iOS 18.5

iPhone 14 Pro Max,iOS 26
附錄:輔助代碼
#import <Foundation/Foundation.h>
#include <chrono>
#include <os/signpost.h>
#include <mach/mach_time.h>
static inline long long now_ns(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (long long)ts.tv_sec * 1000000000LL + ts.tv_nsec;
}
static os_log_t LOG_PERF = os_log_create("com.ufogxl.GCDTest", "Custom");
#define PERF_BEGIN(log, spid, ptr, name) \
spid = os_signpost_id_make_with_pointer(log, (ptr)); \
os_signpost_interval_begin(log, spid, (name), "");
#define PERF_END(log, spid, name) \
os_signpost_interval_end(log, spid, (name), "");
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
// printf("sleep for " TOSTRING(ms) " ms\n");
#define DEFINE_SLEEP_MS_FN(name, ms) \
__attribute__((used)) \
void name(void*_) { \
os_signpost_id_t spid; \
uint64_t now_ns = mach_absolute_time(); \
PERF_BEGIN(LOG_PERF, spid, (void*)now_ns, #name); \
(void)_; \
const uint64_t _ms = (ms); \
mach_timebase_info_data_t info; \
mach_timebase_info(&info); \
uint64_t ns = _ms * 1000000L; \
uint64_t ticks = ns * info.denom / info.numer; \
mach_wait_until(now_ns + ticks); \
PERF_END(LOG_PERF, spid, #name); \
}
//#define DEFINE_SLEEP_MS_FN(name, ms) \
//void name(void*_) { \
// printf("sleep for " TOSTRING(ms) " ms\n"); \
//}
DEFINE_SLEEP_MS_FN(sleep_4ms, 4)
DEFINE_SLEEP_MS_FN(sleep_3ms, 3)
DEFINE_SLEEP_MS_FN(sleep_2ms, 2)
DEFINE_SLEEP_MS_FN(sleep_1ms, 1)
DEFINE_SLEEP_MS_FN(sleep_0ms, 0)
DEFINE_SLEEP_MS_FN(sleep_14ms, 14)
DEFINE_SLEEP_MS_FN(sleep_13ms, 13)
DEFINE_SLEEP_MS_FN(sleep_12ms, 12)
DEFINE_SLEEP_MS_FN(sleep_11ms, 11)
DEFINE_SLEEP_MS_FN(sleep_10ms, 10)