-
workqueue 사용법개발/컴퓨터사이언스 2018. 7. 16. 20:30
workqueue를 사용하는 작업은 크게 queue와 work를 만들고 작업을 스케줄 하는 것으로 나뉜다.
1. Queue 생성
workqueue도 이름에서 짐작 할 수 있듯이 queue이기 때문에 자료구조시간에 지겨울 정도로 봤던 queue를 만들어야 한다. 하지만 push나 pop처럼 queue를 사용하는 함수 API까지 만들어줄 필요는 없고 내가 짓고 싶은 Queue의 이름만 하나만 생각하고 생성 매크로만 호출하면 된다
#define create_workqueue(name) \ alloc_workqueue("%s", __WQ_LEGACY | WQ_MEM_RECLAIM, 1, (name))
리턴인자는 workqueue_struct * 다. 이 포인터를 이용해서 queue에 넣는 작업을 할 수 있다.
2. Work 생성
Work를 생성할 때는 queue처럼 이름까지는 필요 없고 스케줄 될 때 실행할 함수만 있으면 된다. queue처럼 work도 이미 구현된 매크로를 호출해서 간단히 초기화 할 수 있다.
#define INIT_WORK(_work, _func) \ __INIT_WORK((_work), (_func), 0) void acpi_scan_table_handler(u32 event, void *table, void *context) { ... INIT_WORK(&tew->work, acpi_table_events_fn); }
첫번째 인자는 struct work_struct 자료구조의 포인터이고 두번째 인자는 void로 선언된 함수의 포인터다. 일반 콜백 함수를 등록하는 것과 비슷하다. 그 밑의 코드는 실제로 사용하는 예시다. tew->work인 구조체에다가 acpi_table_events_fn 함수를 호출하도록 했다.
3. 스케줄링
delay해서 실행하려는 작업(work)를 만든 queue에다가 넣는 작업이다. 함수 이름만 봐도 대강 무슨 일을 하는지 짐작 할 수 있다.
static inline bool queue_work(struct workqueue_struct *wq, struct work_struct *work) extern bool queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work);
queue_work는 첫번째 인자로 workqueue_struct의 포인터를 받고 두번째 인자로는 실행할 작업인 work_struct를 받는다. queue에다가 작업을 넣는 함수다. 바로 밑의 함수인 queue_work_on은 cpu라는 인자가 있는데 이 인자를 이용해서 스케줄링할 cpu를 선택 할 수 있다.
queue를 선언하지 않고 work만 선언해서 바로 스케줄 할 수 있다. 이때는 queue를 사용하지 않는건 아니고 시스템 부팅때 초기화된 queue(system_wq로 선언돼있다)를 사용해서 스케줄링 한다.
static inline bool schedule_work(struct work_struct *work) static inline bool schedule_work_on(int cpu, struct work_struct *work)
'개발 > 컴퓨터사이언스' 카테고리의 다른 글
스핀락 (0) 2018.07.23 eventfd (0) 2018.07.18 tasklet 사용법 (0) 2018.06.17 tasklet과 workqueue의 차이점 (1) 2018.06.15 ARM64 리눅스 부팅 초기 어셈블리 코드 분석(head.S) (2/2) (0) 2018.01.27