Создает ли create_workqueue() новый рабочий поток?

Я хочу создать новую рабочую очередь, используя create_workqueue()

Автор книги о разработке ядра, которую я читаю, говорит: «Эта функция создает все рабочие потоки (по одному на каждый процессор в системе) и подготавливает их к работе».

Мой код, показанный в конце этого вопроса, создает ядро ​​и планирует работу с двумя очередями. Одна из них является рабочей очередью по умолчанию, а другая использует настроенную рабочую очередь. Они должны обрабатываться разными рабочими потоками.

Однако в результатах (показанных ниже) я вижу, что оба процесса обрабатываются одним и тем же процессом (PID 42501), который является потоком kworker2 на моей виртуальной машине.

Результат выполнения: результат выполнения

детали потока

#include <linux/workqueue.h>
#include "kn_common.h"
#include <linux/sched.h>

MODULE_LICENSE("Dual BSD/GPL");

static void my_work_func(struct work_struct *work){
    long ID;
    printk(KERN_ALERT"=============\n");
    print_current_time(0);
    ID = current->pid;
    printk(KERN_ALERT"my workqueue function is called!.... pid = %ld\n", ID);
    printk(KERN_ALERT"=============\n");
}

static void my_work_custom_func(struct work_struct *work){
    long ID;
    printk(KERN_ALERT"=============\n");
    print_current_time(0);
    ID = current->pid;
    printk(KERN_ALERT"my customize workqueue is called!... pid = %ld\n", ID);
    printk(KERN_ALERT"=============\n");
}

DECLARE_WORK(mywork, my_work_func);

static int testworkqueue_init(void){
    struct workqueue_struct *myworkqueue = create_workqueue("myworkqueue");

    // init a work_struct dynamically use pointer
    struct work_struct *mywork2;
    mywork2 = kmalloc(sizeof(struct work_struct), GFP_KERNEL);
    INIT_WORK(mywork2, my_work_custom_func);

    flush_scheduled_work();

    // schedule work
    schedule_work(&mywork);

    // flush customized workqueue
    flush_workqueue(myworkqueue);
    queue_work(myworkqueue, mywork2);

    return 0;
}

static void testworkqueue_exit(void){
    printk(KERN_ALERT"*************\n");
    print_current_time(0);
    printk(KERN_ALERT"testworkqueu exit\n");
    printk(KERN_ALERT"*************\n");
}

module_init(testworkqueue_init);
module_exit(testworkqueue_exit);

И Makefile

obj-m += myworkqueue.o
myworkqueue-objs := testworkqueue.o kn_common.o


CURRENT_PATH := $(shell pwd)

LINUX_KERNEL := $(shell uname -r)
# you may change this to your own kernel src path
LINUX_KERNEL_PATH := /lib/modules/$(LINUX_KERNEL)/build

all:
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
    rm -rf modules.order Module.symvers .*.cmd *.o *.mod.c .tmp_versions *.unsigned

clean:
    rm -rf modules.order Module.symvers .*.cmd *.o *.mod.c *.ko .tmp_versions *.unsigned

person jiexray    schedule 18.01.2017    source источник


Ответы (1)


Первоначально реализованная многопоточная (MT) рабочая очередь тратила впустую много ресурсов, уровень параллелизма был неудовлетворительным.

Представлен новый дизайн, обеспечивающий высокий уровень параллелизма. Функции create_*workqueue() устарели и должны быть удалены.

Прочтите это, чтобы узнать о последней реализации workqueue.

person Optimus Prime    schedule 18.01.2017