Tuesday, December 1, 2009

SW302 - Лабораторын ажил 8

Энэ лабораторийн ажлаар бид fork/exec -г ашиглан олон бодлогын буюу зэрэг ажилладаг "Хувиргагч програм" зохиох болно.

Програм ажиллах заавар:

  1. Тест хийх өгөгдлийн файл үүсгэнэ. Энэ нь хамгийн 200 кбайт бүхий текст файл байна. Доторх нь юу ч байж болно. Эвтэйхэн байлгах үүднээс энэ текст файлын нэрийг файлдаа хадгалж болно.
  2. Хувиргагчийн үндсэн програмыг үүсгэнэ. Энэ програмд бид fork/exec -г ашиглан 4 хүү процесс үүсгэх ба процесс бүр тест файлын 1/4 (буюу 25%) хувийг хувиргана. Файлтай ажиллах бүх үйлдлүүд (үүсгэх, нээх, хаах) энэ үндсэн програмд хийгдэх ёстой. Өөрөөр хэлбэл  үндсэн програм тестийн файлуудыг нээх ба мөн шинэ файлыг үүсгэх болно. Харин унших, бичих үйлдлийг хүү процессд хийх болно. Хүү процесс нь эцэг процессоос тусдаа програмд байх ба боловсруулалт хийх эхлэл болон хэдэн байт командын мөрөөс авдаг нэг л програм байх болно. Өөрөөр хэлбэл энэ програмын 4 процесс ажиллах болно.
  3. 4 дэд процесс нь тестийн файлын агуулгын 25% -г уншаад хувиргах болно. Хувиргах алгоритмаа өөрөө бодож сонгоорой. Жишээ нь, тэмдэгт бүр дээр ямар нэгэн тоогоор ямар нэгэн үйлдэл, жишээ нь 17-р XOR хийж болох юм.
  4. Дэд процесс бүр өөрийн хувиргах үйл ажиллагаагаа дуусгаад хувирсан үр дүнг шинэ файл руу (үндсэн програмаар үүсгэгдсэн) бичих болно. Дэд процессууд хувирсан өгөгдлийг яг байсан байрлалд нь (гэхдээ шинэ файлд) бичих ёстойг анхаараарай. Жишээ нь, Хэрэв хоёр дугаар процесс өгөгдлийн 2-р 25% дээр ажиллаж байсан бол энэ процесс хувиргасан өгөгдлөө шинэ файлын мөн 2-р 25% -д бичих болно. Файлын заагчийг нь зөв байрлуулах хэрэгтэй гэсэн үг.
  5. Бүх дэд процесс өөрийн ажлаа дуусгасны дараа үндсэн програм нь шаардлагатай цэвэрлэх, хаах ажиллагааг хийгээд дуусах болно.

Эхлээд тест хийх файлаа үүсгэе. (src.txt)

for j in `seq 1 20480`;do echo -n "0123456789" >> src.txt ; done

Одоо үндсэн програмыг үүсгэе.

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>


#define OLD_FILE "src.txt"
#define NEW_FILE "dest.txt"
#define CHILD_RUN "./lab8_child"


#define handle_error(msg) do {perror(msg); exit(EXIT_FAILURE);} while(0);


int forkexec_child(int, int, int, int);


int main(void){
/*Доорх мөрөнд тайлбар хэрэгтэй*/
    int src_fd = open(OLD_FILE, O_RDONLY);
    if(src_fd == -1) handle_error("src open");
/*Доорх мөрөнд тайлбар хэрэгтэй*/  
    int dest_fd = creat(NEW_FILE, S_IRUSR | S_IWUSR);
    if(dest_fd == -1) handle_error("dest open");
    // 200K*25% === 200 * 1024 / 4
/*Доорх мөрөнд тайлбар хэрэгтэй*/
    if( forkexec_child(0, 200*1024/4, src_fd, dest_fd) == -1)  handle_error("forkexec_child1");
    if( forkexec_child(200*1024/4*1, 200*1024/4, src_fd, dest_fd) == -1)  handle_error("forkexec_child2");
    if( forkexec_child(200*1024/4*2, 200*1024/4, src_fd, dest_fd) == -1)  handle_error("forkexec_child3");
    if( forkexec_child(200*1024/4*3, 200*1024/4, src_fd, dest_fd) == -1)  handle_error("forkexec_child4");
/*Доорх мөрөнд тайлбар хэрэгтэй*/  
    int child_exit_status;
    wait(&child_exit_status);
/*Доорх мөрөнд тайлбар хэрэгтэй*/  
    if(child_exit_status != 0) perror("child error");
/*Доорх мөрөнд тайлбар хэрэгтэй*/  
    close(src_fd);
    close(dest_fd);
   
    return 0;
}


int forkexec_child(int start, int length, int src_fd, int dest_fd){
    int c_pid = fork();
/*Доорх мөрөнд тайлбар хэрэгтэй*/
    if( c_pid < 0) perror("fork");
    if( c_pid == 0){
        char buf_start[50];
        char buf_length[50];
        char buf_src_fd[50];
        char buf_dest_fd[50];
/*Доорх мөрөнд тайлбар хэрэгтэй*/
        sprintf(buf_start, "%d", start);
        sprintf(buf_length, "%d", length);
        sprintf(buf_src_fd, "%d", src_fd);
        sprintf(buf_dest_fd, "%d", dest_fd);
/*Доорх мөрөнд тайлбар хэрэгтэй*/
        char *parameters[] = {CHILD_RUN, buf_start, buf_length, buf_src_fd, buf_dest_fd, NULL};
/*Доорх мөрөнд тайлбар хэрэгтэй*/      
        execvp(CHILD_RUN, parameters);
        return -1;
    }
    return 0;
}


Дараа нь хүү програмыг:

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>


#define SCRAMBLER 17


void scramble(char *, int);


int main(int argc, char *argv[]){
    if(argc < 5) { printf("argument error\n");exit(1); }
/*Доорх мөрөнд тайлбар хэрэгтэй*/  
    int start = atoi(argv[1]);
    int length = atoi(argv[2]);
    int src_fd = atoi(argv[3]);
    int dest_fd = atoi(argv[4]);
/*Доорх мөрөнд тайлбар хэрэгтэй*/
    char *buffer = malloc(length);
/*Доорх мөрөнд тайлбар хэрэгтэй*/  
    lseek(src_fd, start, SEEK_SET);
/*Доорх мөрөнд тайлбар хэрэгтэй*/
    read(src_fd, buffer, length);
/*Доорх мөрөнд тайлбар хэрэгтэй*/  
    scramble(buffer, length);
/*Доорх мөрөнд тайлбар хэрэгтэй*/  
    lseek(dest_fd, start, SEEK_SET);
/*Доорх мөрөнд тайлбар хэрэгтэй*/
    write(dest_fd, buffer, length);
   
    return 0;
}


void scramble(char *buf, int length){
    int i;
    for(i = 0; i < length; i++){
/*Доорх мөрөнд тайлбар хэрэгтэй*/
        buf[i] = buf[i] ^ SCRAMBLER;
    }
}


Даалгавар

Дээрх програмуудыг хөрвүүлж ажиллуулж үзнэ. Шаардлагатай мөрнүүдэд тайлбар бичнэ. Тайлбар нь харахад үзэгдэж байгаа зүйлийг давтан хэлэх биш түүний цаад санаа, яагаад шаардлагатайг хэлсэн байх ёстой.

No comments:

Post a Comment