Linux高級 2019-5-11下午

1.併發

1.1 併發的優點:使用多進程的併發程序,可以大大提高程序的執行效率,縮短任務完成的時間

1.2 併發性概述:

  • 併發是指多進程共同完成指定任務可以比單進程獲取CPU使用權的概率更大,及時得到更多的時間片,從而加快完成任務的速度

1.3 串行的概念

  • 從任務的起始位置執行至末尾位置,有次序地執行。

1.4 並行的概念

  • 依賴於硬件支持,有多少核心處理器就有多少並行數量,單核無法進行並行操作。

1.5 完成多進程拷貝文件

  • 1.用戶可以傳遞三個參數,argv[1] 源文件 ,argv[2] 目標文件,argv[3] 進程數;
  • 2.共三個模塊:任務分割,進程創建,文件拷貝(讀寫);
  • 3.對用戶輸入的信息進行處理:邏輯層,邏輯層用來保護程序,校驗用戶輸入;
  • 4.對於源文件,必須存在,否則返回錯誤信息;對於目標文件,有則直接拷貝,無則先創建再拷貝;對於進程數,最小不能小於0,最大不能大於50,否則返回錯誤信息;
  • 5.用戶數據向程序數據轉換,意思即將命令行數據轉換爲程序變量;
  • 6.任務分割:傳入進程數和源文件;
  • 7.進程創建:傳入任務分割的返回值,進程數,並通過 exec 族加載文件拷貝程序;
  • 8.文件拷貝:傳入拷貝位置和拷貝大小;

1.6 創建該項目

  • 1.首先創建一個新文件夾: proj
  • 2.在 proj 文件夾下創建 include(存放該工程的引用頭文件)、 src(存放源文件以及main文件)、 lib(存放動態庫靜態庫)、 bin(存放進行拷貝文件的可執行文件);
  • 3.首先完成bin文件夾下的拷貝文件的程序 copy.c ;
#include <copy.h>

void copy(char* src_path, char* tar_path, char* pos, char* batch_size)
{
	int sfd;
	int tfd;
	int n_pos = atoi(pos);
	int n_batch_size = atoi(batch_size);
	sfd = open(src_path, O_RDONLY);
	tfd = open(tar_path, O_WRONLY|O_CREAT, 0664);
	
	// 將要拷貝文件與完成拷貝文件同時進行偏移以完成分批操作
	lseek(sfd, n_pos, SEEK_SET);
	lseek(tfd, n_pos, SEEK_SET);
	char buf[1024];
	bzero(buf, sizeof(buf));
	int len = read(sfd, buf, n_batch_size);
	write(tfd, buf, len);
	close(sfd);
	close(tfd);
}

int main(int argc, char** argv)
{
	copy(argv[1], argv[2], argv[3], argv[4]);

	return 0;
}
  • 4.其次完成 self_model.c 文件,該文件的功能是對用戶輸入做一個判斷,若用戶輸入有問題,則返回錯誤信息,否則將用戶輸入轉換爲程序認識的變量;用戶輸入信息無效則返回0,有效則返回1;
#include <copy.h>

int self_model(char* src_path, int proc_num)
{
	if((access(src_path, F_OK)) == -1)
		return 0;
	if(proc_num <= 0 || proc_num > 50)
		return 0;
	return 1;
}
  • 5.再次完成 cur_block.c 文件,該文件的功能是將要拷貝的文件進行分塊,按照進程數量進行分塊;
#include <copy.h>

int cur_block(char* src_path, int proc_num)
{
	int sfd;
	int len;
	sfd = open(src_path, O_RDONLY);
	len = lseek(sfd, 0, SEEK_END);
	if(len % proc_num == 0)
		return len/proc_num;
	else
		return len/proc_num + 1;
}
  • 6.完成 create_process.c 文件,該文件的功能是按照進程數創建進程,並讓子進程進行拷貝文件操作;
#include <copy.h>

void create_process(char* src_path, char* tar_path, char* batch_size, char* proc_num)
{
	int n_batch_size = atoi(batch_size);
	pid_t pid;
	int n_proc_num = atoi(proc_num);
	int i = 0;
	for(i; i<n_proc_num; i++)
	{
		pid = fork();
		if(pid == 0)
			break;
	}
	if(pid > 0)
	{
		// 回收操作
	}
	else if(pid == 0)
	{
		printf("Child:%d\tpos:%d\tbatch_size:%d\n", getpid(), i*n_batch_size, n_batch_size);
		char buf1[255];
		sprintf(buf1, "%d", i*n_batch_size);
		char buf2[255];
		sprintf(buf2, "%d", n_batch_size);
		execl("../bin/copy", "copy", src_path, tar_path, buf1, buf2, NULL);
	}
	else
	{
		perror("fork call failed ");
		exit(1);
	}
}
  • 7.創建一個 main.c 函數來作爲最終生成 app 可執行文件的文件;
#include <copy.h>

int main(int argc, char** argv)
{
	int n_proc_num;
	if(argc == 1 || argv == 2)
	{
		printf("TOO LESS ARGVS.\nPLS INPUT LIKE: ./app SOURCE_PATH TARGET_PATH NUMBER_PROCESS[option]\n");
	}
	else if(argc == 3)
		n_proc_num = 10;
	else
		n_proc_num = atoi(argv[3]);

	if(!self_model(argv[1], n_proc_num))
	{
		printf("SOURCE_PATH IS WRONG!\nPLS CHECK SOURCE FILE AND NUMBER OF PROCESS\n");
		exit(1);
	}

	// 將文件切片
	int n_batch_size = cur_block(argv[1], n_proc_num);
	char buf1[255];
	sprintf(buf1, "%d", n_batch_size);
	char buf2[255];
	sprintf(buf2, "%d", n_proc_num);

	// 創建進程進行多進程拷貝
    printf("Begin copy with %d process.\n", n_proc_num);
    create_process(argv[1], argv[2], buf1, buf2);
    printf("DONE.\n");

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章