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;
}