女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux驅動開發_視頻廣告機開發、Linux進程編程介紹

DS小龍哥-嵌入式技術 ? 2022-09-17 15:49 ? 次閱讀

【摘要】 介紹Linux下進程編程、進程的創建、進程通信、完成廣告機項目代碼。

昨天完成的任務: Mplayer播放器安裝成功,并且實現基本使用。

任務1: 學習Linux下進程編程

1.?進程簡介

進程是操作系統調度的最小單元,線程是進程內部的執行單元,一個進程默認有一個主線程。

進程在操作系統里使用PID號作為標識符號----查看當前終端運行的進程: ps 。

poYBAGMlOoiAfax4AAB43IUPk_w877.png

每個進程之間的資源都是獨立的。--------進程可以自己獨立的運行、帶main----------

??今天學習的主要任務:

1. 進程間通信: 管道(無名管道、命名管道)、消息隊列、共享內存、內存映射(mmap)、信號

2. execl函數族: 用于啟動一個新的進程,新的進程開始執行之后,會覆蓋原來進程空間。

3. dup2函數: 復制文件表。------實現文件描述符重定向。 dup2(fds[1],1);

4. 編寫廣告機播放器程序

5. 編寫shell腳本,實現文件同步

1.1 進程創建

#include

pid_t fork(void);

功能: 在當前進程里再創建一個子進程。

函數返回值: ==0 表示子進程,>0表示父進程,<0表示出現錯誤

新創建的子進程特性: 在fork成功那一刻,會將父進程所有的資源全部拷貝一份,重新運行。

??僵尸進程: 子進程先退出,父進程沒有清理子進程的空間。如何清理子進程空間? wait();

??孤兒進程: 父進程比子進程先退出。避免,就是父進程要保證最后退出。

1.2 等待子進程退出,并且清理子進程空間

#include

#include

pid_t wait(int *status);

函數功能: 隨機等待一個子進程退出,并清理子進程資源。

返回值: 返回退出的子進程PID號。

函數的形參: int *status可以保存進程退出的狀態。 exit(-1); //結束當前進程。

pid_t waitpid(pid_t pid, int *status, int options);

函數: 可以指定特定的PID號。-1表示所有子進程。

#include

#include

#include

#include

#include

#include

#include

int main(int argc,char **argv)

{

int pid;


/*創建子進程*/

pid=fork();

if(pid==0) //子進程

{

printf("子進程正常運行!....\n");

sleep(1);


/*結束當前進程*/

exit(0);

}

else if(pid>0) //父進程

{

int state=0; //保存子進程退出狀態值

/*阻塞-等待子進程退出*/

wait(&state);

printf("父進程提示: 子進程已經安全退出! 子進程退出的狀態=%d\n",state);

}

else

{

printf("進程創建錯誤!");

}

return 0;

}

1.3 終止當前進程

#include

void _exit(int status);

#include

void _Exit(int status);

#include

void exit(int status);

1.4 管道通信

管道: FIFO文件,特性: 先入先出。

1.4.1 無名管道: 有親緣關系之間的進程才可以使用無名管道進程通信。

無名管道這個FIFO文件沒有實體。

如果創建無名管道?

#include

int pipe(int pipefd[2]);

函數形參: 傳入一個數組的首地址。

管道創建成功之后: [0]表示(FIFO)無名管道讀端。 [1]表示(FIFO)無名管道寫端。

9cc4.png

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc,char **argv)

{

int pid;

int pipefd[2];

/*創建無名管道*/

pipe(pipefd);


/*創建子進程*/

pid=fork();

if(pid==0) //子進程

{

printf("子進程正常運行!....\n");

sleep(1);


char *p="1234567";

write(pipefd[1],p,strlen(p)+1); //向管道的寫端寫入數據


/*結束當前進程*/

exit(0);

}

else if(pid>0) //父進程

{

int state=0; //保存子進程退出狀態值


char buff[100];

read(pipefd[0],buff,100); //從管道的讀端讀取數據

printf("父進程收到的數據=%s\n",buff);


/*阻塞-等待子進程退出*/

wait(&state);

printf("父進程提示: 子進程已經安全退出! 子進程退出的狀態=%d\n",state);

}

else

{

printf("進程創建錯誤!");

}

return 0;

}

1.4.2 命名管道通信

命名管道可以在任何進程間通,因為命名管道是一個實體文件,在磁盤可用找到該FIFO文件。

如何在磁盤上創建管道文件:

#include

#include

int mkfifo(const char *pathname, mode_t mode);

管道文件不能在共享目錄下創建。(掛載的目錄)

1.5 dup2函數學習

#include

int dup2(int oldfd, int newfd);

示例: dup2(fds[1],1); //接下來對文件描述符1的操作都是相當于對管道fds[1]操作。

文件描述符在內核里對應的是一個文件結構體。

??示例1:

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc,char **argv)

{

int pid;

int pipefd[2];

/*創建無名管道*/

pipe(pipefd);


/*創建子進程*/

pid=fork();

if(pid==0) //子進程

{

printf("子進程正常運行!....\n");


dup2(pipefd[1],1);

//pipefd[1]管道寫端,1表示當前進程的標準輸出

sleep(1);

printf("---1234567---\n");


/*結束當前進程*/

exit(0);

}

else if(pid>0) //父進程

{

int state=0; //保存子進程退出狀態值


char buff[100];

read(pipefd[0],buff,100); //從管道的讀端讀取數據

printf("父進程收到的數據=%s\n",buff);


/*阻塞-等待子進程退出*/

wait(&state);

printf("父進程提示: 子進程已經安全退出! 子進程退出的狀態=%d\n",state);

}

else

{

printf("進程創建錯誤!");

}

return 0;

}

??示例2: 日志功能制作。

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc,char **argv)

{

/*1.創建存放日志的文件*/

int fd=open("/log.txt",O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);


/*2. 重定向(將標準輸出重定向到fd)*/

dup2(fd,1);


/*3. 向日志文件寫入數據*/

printf("12345\n");

printf("abcd\n");

printf("日志文件測試!\n");


/*4. 關閉日志文件*/

close(fd);

return 0;

}

1.6 execl 函數族

#include

extern char **environ;

int execl(const char *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(const char *path, const char *arg,..., char * const envp[]);

int execv(const char *path, char *const argv[]);

int execvp(const char *file, char *const argv[]);

execl功能介紹: 啟動新的子進程,當子進程啟動成功之后會覆蓋原來的進程空間。

Execl函數族介紹:

1.?帶p表示可執行文件可以從環境變量里獲取。

2.?不帶p表示,可執行文件需要填絕對路徑。

3.?帶e表示最后的參數,可以給新進程設置新的環境變量。

說明: 參數列表最后面都要加一個NULL。

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc,char **argv)

{

/*以ls命令為例子,講解*/

//execl(<可執行程序的路徑>,<執行的形參列表>,NULL);


//execl("/bin/ls","ls","-l",NULL);


//execlp("ls","ls","-l",NULL);


//char *envp[]={"PATH1=12345",NULL};

//execle("/bin/ls","ls","-l",NULL,envp);

//獲取環境變量的值: getenv("PATH1");


//char *argvs[]={"ls","-l",NULL};

//execv("/bin/ls",argvs);


char *argvs[]={"ls","-l",NULL};

execvp("ls",argvs);


printf("執行失敗!\n");

return 0;

}

//ls -l

1.7 mplayer播放器

Mplayer運行有兩個模式: 1. 主模式 2.從模式

pYYBAGMlOpOACkU0AAFMwIhnoNQ390.png

#include

#include

#include

#include

#include

#include

#include

#include

#include

/*

獲取標準輸入的數據、寫給FIFO文件

*/

void *pthread_func(void *argv)

{

int fd=open("/mplayer_fifo",2);

if(fd<0)

{

printf("FIFO文件打開失敗!\n");

pthread_exit(NULL); //結束當前線程

}

char buff[100];

int len;

while(1)

{

printf("請輸入命令:");

fflush(stdin); //刷新緩沖區

fgets(buff,100,stdin); //從鍵盤上獲取數據 get_percent_pos get_file_name

len=strlen(buff); // get_file_name [0~12] [13]='\n'

write(fd,buff,len); // get_file_name '\n'

memset(buff,0,100);

}

}

int main(int argc,char **argv)

{

int pid;


/*1. 創建無名管道*/

int fds[2];

pipe(fds);


/*2. 創建子進程*/

pid=fork();


/*子進程代碼: mplayer播放器*/

if(pid==0)

{

/*將子進程的標準輸出重定向到管道寫端*/

dup2(fds[1],1);


/*啟動子進程*/

execlp("mplayer","mplayer","-zoom","-x","800","-y","480","-slave","-quiet","-input","file=/mplayer_fifo","/work/video_file/Video_2018-12-11.wmv",NULL);

}

else /*父進程*/

{

char buff[100];

int cnt=0;


/*創建新的線程: 從鍵盤上獲取輸入的數據,寫給播放器的FIFO文件*/

pthread_t threadID;

pthread_create(&threadID,NULL,pthread_func,NULL);

pthread_detach(threadID); //設置分離屬性


while(1)

{

/*從管道的讀端讀取數據: 讀取就是mplayer播放器輸出的數據*/

cnt=read(fds[0],buff,100);

buff[cnt]='\0';

printf("播放器輸出的值=%s\n",buff);

}

}

return 0;

}

任務2: 廣告機項目

??廣告機項目要求:

廣告機應用場景: 公交站臺、地鐵車廂、銀行前臺大廳、高速公路、公園….

1.?有些廣告機只有視頻播放,沒有聲音。

2.?廣告機都支持網絡視頻文件更新---->文件更新使用現成的服務器: FTP服務器、NFS服務器。

(1)?如何判斷服務器上那些文件需要下載到本地? 通過shell腳本代碼或者使用C語言

(2)?更新的時間一般是固定的: 20:00 23:00 …… 通過時間函數判斷時間是否到達。

(3)?在視頻文件更新的時候,視頻需要停止播放,可以在屏幕上顯示提示(正在更新…..)。

3.?廣告機需要支持自動播放,播放一個自動切換下一個、循環播放。

調用讀目錄、循環遍歷目錄、得到視頻文件、mplayer播放器需要使用子進程方式啟動。

廣告機: 音量調整、選擇視頻播放…….都不是廣告機的功能---是視頻播放器的功能。

poYBAGMlOpSACaywAADXbVHn7Jg884.png
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/*-----------全局變量區------------*/
int log_fd;  /*保存日志文件的文件描述符*/
#define LOG_FILE "/log.txt"   /*日志文件存放的路徑*/
DIR *video_dir_p=NULL; /*存放視頻的目錄: 打開的目錄指針*/
int video_state=0;

#define VIDEO_FILE_PATH "/work/video_file/" //存放視頻文件的目錄
#define UPDATE_HOUR 16 //更新的時間: 小時
#define UPDATE_MIN 38  //更新的時間: 分鐘
#define UPDATE_SEC 00  //更新的時間: 秒

/*-------函數聲明---------*/
void DeleteListALLNode(void);
/*定義鏈表使用的結構體*/
struct VideoList
{
	char *file_path;
	struct VideoList *next;
};

/*鏈表頭*/
struct VideoList *ListHead=NULL;
/*函數: 信號處理函數*/
void exit_sighandler(int sig)
{
	/*1. 判斷是什么信號*/
	if(sig==2)
	{
		printf("用戶終止了進程!\n");
	}
	else if(sig==11)
	{
		printf("進程訪問了非法內存空間!\n");
	}
	
	/*2. 殺死父進程對應所有子進程*/
	char cmd_buff[100];
	//殺死父進程創建所有子進程,父進程本身不受影響
	sprintf(cmd_buff,"pkill -9 -P %d",getpid());
	system(cmd_buff);
	sleep(2);
	
	/*3. 關閉打開所有的文件或者目錄*/
	close(log_fd); 
	closedir(video_dir_p);
	DeleteListALLNode();
	
	/*4. 退出父進程*/
	exit(1);
}

/*
函數功能: 獲取本地時間,判斷是否是否到達預設的時間
*/
void *Time_pthread_func(void *argv)
{
	time_t time1;
	time_t time2;
	struct tm *system_time;
	char cmd_buff[100];
	while(1)
	{
		time1=time(NULL); //獲取當前系統的時間秒單位
		if(time1!=time2)  //保證if每1秒進去一次
		{
			time2=time1;
			system_time=localtime(&time1); //將秒單位時間,轉成標準時間結構
			printf("%d-%d-%d\n",system_time->tm_hour,system_time->tm_min,system_time->tm_sec);
			/*更新的時間*/
			if(system_time->tm_hour==UPDATE_HOUR 
			&& system_time->tm_min==UPDATE_MIN
			&& system_time->tm_sec==UPDATE_SEC)
			{
				video_state=1; //表示進程需要終止
				
				//"pkill -9 -P <父進程的PID>" 
				//殺死父進程創建所有子進程,父進程本身不受影響
				sprintf(cmd_buff,"pkill -9 -P %d",getpid());
				
				/*執行命令*/
				system(cmd_buff);
				printf("正在結束子進程!\n");
				pthread_exit(NULL);
			}
		}
	}
}
/*
函數功能: 掃描目錄下的所有文件,加載到鏈表里
*/
void ScanDirFile()
{
	struct dirent *dir_file;
	struct VideoList *head_p=ListHead; //保存鏈表頭的地址
	struct VideoList *new_p=NULL;
	
	while(dir_file=readdir(video_dir_p))
	{
		//過濾掉.和..
		if(strcmp(dir_file->d_name,".")==0 || strcmp(dir_file->d_name,"..")==0)
		{
			continue;
		}
		
		//創建新節點
		new_p=(struct VideoList*)malloc(sizeof(struct VideoList));
		if(new_p==NULL)
		{
			printf("創建新節點空間申請錯誤!\n");
			return;
		}
		
		//申請存放文件名稱的空間
		new_p->file_path=malloc(strlen(VIDEO_FILE_PATH)+strlen(dir_file->d_name)+1);
		if(new_p->file_path==NULL)
		{
			printf("申請存放文件名稱的空間錯誤!\n");
			return;
		}
		
		//拼接路徑
		strcpy(new_p->file_path,VIDEO_FILE_PATH);
		strcat(new_p->file_path,dir_file->d_name);
		
		printf("播放的列表:%s\n",new_p->file_path);
		
		//添加新的節點
		while(head_p->next!=NULL)
		{
			head_p=head_p->next;
		}
		
		head_p->next=new_p;
		new_p->next=NULL;
	}
}

/*
函數功能: 刪除鏈表節點
*/
void DeleteListALLNode(void)
{
	struct VideoList *head_p=ListHead; //保存鏈表頭的地址
	struct VideoList *tmp_p;
	struct VideoList *delete_p;
	
	if(head_p!=NULL && head_p->next==NULL)
	{
		free(head_p); //釋放鏈表頭
	}
	else if(head_p->next!=NULL)
	{
		tmp_p=head_p->next;
		free(head_p); //釋放鏈表頭
		
		while(tmp_p->next!=NULL)
		{
			delete_p=tmp_p;
			tmp_p=tmp_p->next;
			
			free(delete_p->file_path);
			free(delete_p);
		}
		
		free(tmp_p->file_path);
		free(tmp_p);
	}
}

int main(int argc,char **argv)
{
	int pid;
	int state=0;
	struct VideoList *next_p=ListHead;
	
	/*1. 注冊將要捕獲的信號*/
	signal(SIGINT,exit_sighandler);   /*進程終止信號:Ctrl+C*/
	signal(SIGSEGV,exit_sighandler);  /*進程訪問了非法內存*/
	
	/*2. 創建日志文件: 保存mplayer播放器的輸出*/
	log_fd=open(LOG_FILE,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);
	
	/*3. 打開目錄*/
	video_dir_p=opendir(VIDEO_FILE_PATH);
	if(video_dir_p==NULL)
	{
		printf("%s 存放視頻的目錄打開失敗!\n",VIDEO_FILE_PATH);
		exit(1);
	}
	
	/*4. 創建新的線程:判斷更新時間*/
	pthread_t threadID;
	pthread_create(&threadID,NULL,Time_pthread_func,NULL);
	pthread_detach(threadID); //設置分離屬性
		
	/*5. 遍歷目錄,更新鏈表*/
	//創建鏈表頭
	ListHead=(struct VideoList*)malloc(sizeof(struct VideoList));
	if(ListHead==NULL)
	{
		printf("鏈表頭創建失敗!\n");
		exit(1);
	}
	ListHead->next=NULL; //下個節點為NULL
	
	//掃描目錄,并將目錄下的文件添加到鏈表
	ScanDirFile();
	
	next_p=ListHead; 	 //鏈表頭
	next_p=next_p->next; //取出數據節點
	
LOOP: //該標簽表示繼續播放下一個視頻時,重復創建子進程

	printf("正在播放視頻名稱:%s\n",next_p->file_path);
	/*創建子進程*/
	pid=fork();

	/*子進程代碼: mplayer播放器*/
	if(pid==0)
	{
		/*將子進程的標準輸出重定向到日志文件*/
		dup2(log_fd,1);
		
		/*啟動子進程*/
		execlp("mplayer","mplayer","-zoom","-x","800","-y","480","-slave","-quiet","-input","file=/mplayer_fifo",next_p->file_path,NULL);
	}
	 /*父進程代碼: 控制播放*/
	else
	{
		/*等待子進程退出*/
		wait(&state);
		
		//判斷是否需要結束當前進程
		if(video_state==1)
		{
			/*執行外部腳本: 啟動視頻文件更新*/
			system("./update_video.sh");
			
			/*退出父進程*/
			DeleteListALLNode();
			close(log_fd); 
			closedir(video_dir_p);
			exit(0);
		}
		
		/*遍歷鏈表的下一個節點,取出文件名稱,傳遞給子進程*/
		if(next_p->next==NULL) //表示視頻播放完畢
		{
			printf("視頻播放完畢---->鏈表歸位!\n");
			next_p=ListHead; 	 //鏈表頭
			next_p=next_p->next; //取出數據節點
		}
		next_p=next_p->next;   //取出數據節點
		
		/*再次啟動子進程,播放下一個視頻*/
		goto LOOP; 
	}
	return 0;
}
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11456

    瀏覽量

    212739
  • 編程
    +關注

    關注

    88

    文章

    3679

    瀏覽量

    94852
  • 廣告機
    +關注

    關注

    1

    文章

    164

    瀏覽量

    9982
  • 進程
    +關注

    關注

    0

    文章

    206

    瀏覽量

    14211
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    Linux系統進程管理入門指南

    Linux 系統中,進程是正在運行的程序的實例。理解進程的管理、查看和控制對于系統管理員和開發者來說非常重要
    的頭像 發表于 04-22 14:34 ?288次閱讀
    <b class='flag-5'>Linux</b>系統<b class='flag-5'>進程</b>管理入門指南

    硬核升級!華清遠見STM32MP157驅動開發課程助力嵌入式Linux底層開發入門進階

    在嵌入式Linux系統開發中,驅動程序開發是一項關鍵技術,它作為硬件與軟件之間的橋梁,實現了操作系統對硬件設備的控制。相較于嵌入式Linux
    的頭像 發表于 04-03 16:40 ?312次閱讀
    硬核升級!華清遠見STM32MP157<b class='flag-5'>驅動</b><b class='flag-5'>開發</b>課程助力嵌入式<b class='flag-5'>Linux</b>底層<b class='flag-5'>開發</b>入門進階

    [迅為]Linux開發小技巧:Remote - SSH插件

    [迅為]Linux開發小技巧:Remote - SSH插件
    的頭像 發表于 04-01 15:46 ?391次閱讀
    [迅為]<b class='flag-5'>Linux</b><b class='flag-5'>開發</b>小技巧:Remote - SSH插件

    迅為RK3568開發驅動指南Linux中通用SPI設備驅動

    迅為RK3568開發驅動指南Linux中通用SPI設備驅動
    的頭像 發表于 01-23 11:02 ?2479次閱讀
    迅為RK3568<b class='flag-5'>開發</b>板<b class='flag-5'>驅動</b>指南<b class='flag-5'>Linux</b>中通用SPI設備<b class='flag-5'>驅動</b>

    Linux應用編程的基本概念

    Linux應用編程涉及到在Linux環境下開發和運行應用程序的一系列概念。以下是一些涵蓋Linux應用
    的頭像 發表于 10-24 17:19 ?552次閱讀

    Linux開發怎么學?

    Linux開發怎么學? 學習 Linux 是一個循序漸進、持續不斷的過程。我們可以從以下幾個方面開始 1.了解 Linux 的歷史和發展: 了解
    發表于 10-10 14:34

    北京迅為RK3568開發板嵌入式學習之Linux驅動全新更新-CAN+

    北京迅為RK3568開發板嵌入式學習之Linux驅動全新更新-CAN+
    的頭像 發表于 09-04 15:29 ?898次閱讀
    北京迅為RK3568<b class='flag-5'>開發</b>板嵌入式學習之<b class='flag-5'>Linux</b><b class='flag-5'>驅動</b>全新更新-CAN+

    嵌入式linux開發的基本步驟有哪些?

    嵌入式Linux開發是一個復雜的過程,涉及到硬件選擇、操作系統移植、驅動開發、應用程序開發等多個方面。以下是嵌入式
    的頭像 發表于 09-02 09:11 ?1042次閱讀

    嵌入式linux開發板怎么操作

    開發板概述 嵌入式Linux開發板是一種專門為嵌入式系統開發而設計的硬件平臺。它具有體積小、功耗低、性能高等特點,廣泛應用于工業控制、智能家居、醫療設備、汽車電子等領域。與傳統的PC
    的頭像 發表于 09-02 09:09 ?674次閱讀

    嵌入式linux開發板芯片的工作原理

    嵌入式Linux開發板是一種基于Linux操作系統的嵌入式系統開發平臺,它廣泛應用于工業控制、智能家居、智能交通、醫療設備等領域。 嵌入式Linux
    的頭像 發表于 09-02 09:07 ?705次閱讀

    linux開發板與樹莓派的區別

    操作系統的微型計算機,主要用于教育、編程、媒體播放等領域。 硬件配置 Linux開發板:Linux開發板的硬件配置因廠商和型號而異,通常包括
    的頭像 發表于 08-30 15:34 ?1731次閱讀

    linux開發板和單片開發的區別

    、PIC等,處理能力和內存容量相對較低。 操作系統 Linux開發板通常使用Linux操作系統,具有豐富的軟件資源和開發工具。單片
    的頭像 發表于 08-30 15:30 ?1816次閱讀

    linux驅動程序如何加載進內核

    Linux系統中,驅動程序是內核與硬件設備之間的橋梁。它們允許內核與硬件設備進行通信,從而實現對硬件設備的控制和管理。 驅動程序的編寫 驅動程序的編寫是
    的頭像 發表于 08-30 15:02 ?942次閱讀

    Linux 驅動開發與應用開發,你知道多少?

    一、Linux驅動開發與應用開發的區別開發層次不同:Linux
    的頭像 發表于 08-30 12:16 ?1390次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>驅動</b><b class='flag-5'>開發</b>與應用<b class='flag-5'>開發</b>,你知道多少?

    深入探討Linux進程調度器

    Linux操作系統作為一個開源且廣泛應用的操作系統,其內核設計包含了許多核心功能,而進程調度器(Scheduler)就是其中一個至關重要的模塊。進程調度器負責決定在任何給定的時刻哪個進程
    的頭像 發表于 08-13 13:36 ?1181次閱讀
    深入探討<b class='flag-5'>Linux</b>的<b class='flag-5'>進程</b>調度器