iT邦幫忙

2024 iThome 鐵人賽

DAY 19
0

實時 POSIX 線程調度(RT pthread scheduling)是指在 POSIX 標準中為實時應用程序提供的線程調度機制。它允許開發者為線程設置優先級,以確保在實時系統中能夠滿足時間約束。

主要特點:

  1. 優先級調度

    • RT pthreads 允許設置不同的優先級,這樣高優先級的線程可以在低優先級線程之前執行。
  2. 調度策略

    • 提供多種調度策略,例如 FIFO(先進先出)和 Round Robin(輪轉調度),以適應不同的應用需求。
  3. 實時性

    • 針對需要嚴格時間控制的應用(如工業控制、醫療設備等),RT pthreads 提供了更高的可靠性和可預測性。
  4. 互斥和同步

    • 支持互斥鎖和條件變量,幫助管理線程之間的資源共享和同步。
  5. 兼容性

    • RT pthreads 與標準 POSIX 線程(pthread)兼容,這意味著開發者可以在現有的 pthread 應用中輕鬆集成實時功能。

使用場景:

RT pthread scheduling 常見於需要高可靠性和可預測性的系統,如嵌入式系統、航空航天、汽車電子等領域。

這種調度機制使開發者能夠更好地控制線程的執行順序和時間,從而滿足實時系統的需求。

posix-rt.c

/**
 * A simple pthread program illustrating RT pthread scheduling.
 *
 * Figure 6.20
 *
 * To compile:
 *
 *	gcc posix-rt.c -o posix-rt -lpthread
 *
 * @author Gagne, Galvin, Silberschatz
 * Operating System Concepts  - Ninth Edition
 * Copyright John Wiley & Sons - 2013.
 */

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>  // 引入此標頭以使用 malloc 和 free
#include <unistd.h>  // 引入此標頭以使用 getpid 和 sleep
#define NUM_THREADS 5

/* the thread runs in this function */
void *runner(void *param); 

main(int argc, char *argv[])
{
	int i, policy;
	pthread_t tid[NUM_THREADS]; 	/* the thread identifier */
	pthread_attr_t attr; 		/* set of attributes for the thread */

	/* get the default attributes */
	pthread_attr_init(&attr);

	/* get the current scheduling policy */
	if (pthread_attr_getschedpolicy(&attr,&policy) != 0)
		fprintf(stderr, "Unable to get policy.\n");
	else {
		if (policy == SCHED_OTHER)
			printf("SCHED_OTHER\n");
		else if (policy == SCHED_RR)
			printf("SCHED_RR\n");
		else if (policy == SCHED_FIFO)
			printf("SCHED_FIFO\n");
	}
	
	/* set the scheduling policy - FIFO, RT, or OTHER */
	if (pthread_attr_setschedpolicy(&attr, SCHED_OTHER) != 0)
		printf("unable to set scheduling policy to SCHED_OTHER \n");

	/* create the threads */
	for (i = 0; i < NUM_THREADS; i++) {
	        int *arg = malloc(sizeof(*arg));  // 動態分配記憶體以傳遞執行緒編號
        	if (arg == NULL) {
            		fprintf(stderr, "Failed to allocate memory.\n");
            		exit(1);
        	}
        	*arg = i;  // 傳遞執行緒編號
       		pthread_create(&tid[i], &attr, runner, arg);  
	}
	/**
	 * Now join on each thread
	 */
	for (i = 0; i < NUM_THREADS; i++) 
		pthread_join(tid[i], NULL);
}

/**
 * The thread will begin control in this function.
 */
void *runner(void *param) 
{
	int thread_id = *((int *)param);  // 取得執行緒編號
	free(param);  // 釋放動態分配的記憶體

    	// 獲取當前進程的 PID
    	pid_t pid = getpid();
    	printf("Thread %d running in process with PID: %d\n", thread_id, pid);

	// 查詢當前執行緒的調度策略
    	pthread_attr_t attr;
    	int policy;
    	pthread_getattr_np(pthread_self(), &attr);
    	pthread_attr_getschedpolicy(&attr, &policy);

    	if (policy == SCHED_OTHER)
        	printf("Thread %d: SCHED_OTHER\n", thread_id);
    	else if (policy == SCHED_RR)
        	printf("Thread %d: SCHED_RR\n", thread_id);
    	else if (policy == SCHED_FIFO)
        	printf("Thread %d: SCHED_FIFO\n", thread_id);

    	// 根據執行緒編號執行不同的工作
    	printf("Thread %d is doing some work...\n", thread_id);
    	sleep(1);  // 模擬工作延遲
    	pthread_exit(0);
}

Terminal
編譯並執行

gcc posix-rt.c -o posix-rt -lpthread
sudo ./posix-rt

結果:
https://ithelp.ithome.com.tw/upload/images/20241003/20168766LICGVjQw4F.png
if (pthread_attr_setschedpolicy(&attr, SCHED_OTHER) != 0),把將線程的調度策略設置為 SCHED_OTHER,這是非實時的調度策略。
原本想改成 SCHED_FIFO 試試看,即便用 sudo 去執行結果卻是:雖然在主執行緒中成功設置了調度策略為 SCHED_FIFO,但是在每個執行緒中查詢時卻顯示為 SCHED_OTHER。這表明執行緒的調度屬性未正確繼承 。

參考:greggagne/OSC9e/ch6/posix-rt.c


上一篇
ch5圖5.8-Pthread排班API
下一篇
ch6-生產者—消費者問題 race condition
系列文
十年後重讀作業系統恐龍本30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言