Spróbujmy kolejnej optymalizacji, rezygnuję z funkcji systemu operacyjnego exit(), zostając przy samym fork():


C++ - fork
//// Copyright (c) 2016 Rafal Jackiewicz//// Indent style: Berkeley//#include <iostream>#include <iomanip>#include <stdio.h>#include <errno.h>#include <sys/wait.h>#include <fcntl.h>#include <sstream>#include <sys/times.h>#include <sys/time.h>#include <sys/resource.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <sys/ipc.h>#include <sys/shm.h>#include <fstream>#define Dneedle_max 6#define Dnew_line 10using namespace std;const int maxPar = 3;const int maxProcess = 32;static int end_main = 0;int fd;int maxproc = 0;unsigned long len_max;const key_t shm_id = 8274;char *fileinmemory;char needle[Dneedle_max];struct stat fd_st;struct process_struct { pid_t pid; int returnCode; time_t timeProcSystem_us; time_t timeProcUser_us; time_t countTimeProcess_start; time_t countTimeProcess_stop; char *shm_start; unsigned long shm_diff; unsigned long shm_len; int shm_return_len;};struct tms bufor;struct process_struct *process = new process_struct[maxProcess];void sygnal(int signo, siginfo_t * sigf, void *b);intmain(int argc, char *argv[]){ pid_t pid_tmp; sigset_t sig_mask; int returnCode, opt_check; int i; struct rusage timeData; struct sigaction sigA; long adressum = 0; unsigned long sizetmp; unsigned long shmComputeDiv; char *copyfim = 0; if (argc == 1) { cout << "Nie podano parametrow w wywolaniu programu." << endl; return 128; } if (argc > (maxPar + 1)) { cout << "Za duzo parametrow, maksymalnie podaj " << maxPar << " parametrow." << endl; return 129; } if (argc < (maxPar + 1)) { cout << "Za malo parametrow, podaj " << maxPar << " parametrow." << endl; return 129; } while ((opt_check = getopt(argc, argv, "vh")) != (-1)) { switch (opt_check) { case 'v': cout << "Versja 1.0\n" << endl; return 130; case 'h': cout << "Poprawne wywolanie programu: szukany ciąg 6 znaków, plik, ile procesów." << endl; cout << "Maksymalnie podaj " << maxPar << " parametrów." << endl; return 130; } } fd = open(argv[2], O_RDONLY); if (fd == -1) { perror("Multifind: open."); return 1; } if (fstat(fd, &fd_st) == -1) { perror("Multifind: fstat."); return 1; } if (!S_ISREG(fd_st.st_mode)) { fprintf(stderr, "%sMultifind: to nie plik.\n", argv[2]); return 1; } len_max = fd_st.st_size; // System V API int smid = shmget(shm_id, len_max, IPC_CREAT | SHM_NORESERVE | 0666); fileinmemory = (char *) shmat(smid, NULL, 0); if (*fileinmemory == -1) { perror("Multifind: shmat."); return 1; } int readerr = read(fd, fileinmemory, len_max); if (readerr == -1) { fprintf(stderr, "Multifind: read."); return 1; } if (close(fd) == -1) { perror("Multifind: close."); return 1; } if (strlen(argv[1]) != Dneedle_max) { fprintf(stderr, "%sZla dlugośc needle.\n", argv[1]); return 1; } else { strcpy(needle, argv[1]); } maxproc = atoi(argv[3]); if (maxproc > maxProcess) { fprintf(stderr, "Multifind: za duzo prosesow."); return 1; } else { if (maxproc == 0) { fprintf(stderr, "Multifind: podales zero procesow."); return 1; } } shmComputeDiv = len_max / maxproc; for (i = 0; i < maxproc; ++i) { process[i].shm_start = fileinmemory + (shmComputeDiv * (i)); process[i].shm_len = shmComputeDiv; } process[maxproc - 1].shm_len = (fileinmemory + len_max) - process[maxproc - 1].shm_start; printf("@ fileinmemory: %p \n", fileinmemory); printf("@ len_max: 0x%lX \n", len_max); printf("@ sum: 0x%lX \n", (long unsigned) fileinmemory + len_max); for (i = 1; i < maxproc; ++i) { sizetmp = process[i - 1].shm_len; copyfim = process[i - 1].shm_start; while ((copyfim[sizetmp] != (char) Dnew_line)) { // || // sizetmp!=0 --sizetmp; } process[i - 1].shm_len = sizetmp; process[i].shm_start = process[i - 1].shm_start + process[i - 1].shm_len; } process[maxproc - 1].shm_len = (fileinmemory + len_max) - process[maxproc - 1].shm_start; printf("\n"); for (i = 0; i < maxproc; ++i) { process[i].shm_diff = process[i].shm_start - fileinmemory; } adressum = 0; for (i = 0; i < maxproc; ++i) { printf("%2d: shm_start: %p ", i, process[i].shm_start); printf(" shm_len: %lX ", process[i].shm_len); printf(" shm_diff: %8lX ", process[i].shm_diff); adressum += process[i].shm_len; printf(" shm_start+shm_len: %lX \n", process[i].shm_len + (long int) process[i].shm_start); } printf("Addr len_max: %lX \n", len_max); printf(" Diff sum: %lX \n", adressum); printf("\n"); sigemptyset(&sig_mask); sigfillset(&sig_mask); sigA.sa_handler = NULL; sigA.sa_sigaction = sygnal; sigA.sa_mask = sig_mask; sigA.sa_flags = SA_SIGINFO; sigA.sa_restorer = NULL; if (sigaction(SIGCHLD, &sigA, NULL)) { perror("Blad sigaction:"); exit(33); } for (int i = 0; i < maxproc; i++) { process[i].countTimeProcess_start = times(&bufor); process[i].pid = fork(); switch (process[i].pid) { case -1: cout << "Nie mozna utworzyc nowego procesu nr: " << i << endl; break; case 0:{ // ###############################################3 const int needle_max = Dneedle_max; unsigned long child_len_max = process[i].shm_len; char *child_fileinmemory; int needle_max_minusone = needle_max - 1; child_fileinmemory = fileinmemory + process[i].shm_diff; char *endfileinmemory = child_fileinmemory + child_len_max - needle_max + 1; char *mark = child_fileinmemory; char *copymarkstart, *copymarkstop; char *needle_maxminus = needle + needle_max_minusone; char *needle_plus = needle + 1; unsigned long needle_max_minustwo = needle_max - 2; unsigned long copylen_max = child_len_max; char *mark_buff = mark; int count_buff; while ((mark = (char *) memchr(mark, *needle, copylen_max)) && (mark < endfileinmemory)) { if (mark[needle_max_minusone] == *needle_maxminus) { if (memcmp (++mark, needle_plus, needle_max_minustwo) == 0) { copymarkstart = mark; while (*(--copymarkstart) != (char) Dnew_line); copymarkstop = mark + needle_max; while (*(++copymarkstop) != (char) Dnew_line); mark = copymarkstop; count_buff = copymarkstop - copymarkstart; memmove(mark_buff, ++copymarkstart, count_buff); mark_buff += count_buff; copylen_max = endfileinmemory - mark; break; } else { --copylen_max; } } else { ++mark; --copylen_max; } } while ((mark = (char *) memchr(mark, *needle, copylen_max)) && (mark < endfileinmemory)) { if (mark[needle_max_minusone] == *needle_maxminus) { if (memcmp (++mark, needle_plus, needle_max_minustwo) == 0) { copymarkstart = mark; while (*(--copymarkstart) != (char) Dnew_line); copymarkstop = mark + needle_max; while (*(++copymarkstop) != (char) Dnew_line); mark = copymarkstop; count_buff = copymarkstop - copymarkstart; memcpy(mark_buff, ++copymarkstart, count_buff); mark_buff += count_buff; copylen_max = endfileinmemory - mark; } else { --copylen_max; } } else { ++mark; --copylen_max; } } int *tmmp = (int *) (child_fileinmemory + child_len_max - 8); *tmmp = mark_buff - child_fileinmemory; return (44); break; } default: break; } } do { pause(); } while (end_main < (maxproc - 1)); // uzywam wait pokazujac zachowanie sie tablicy stanu procesu po jego // zakonczeniu // te dzialania mozna przeniesc do funkcji obslugujacej sygnal // i odpytywac sie tam o stan procesu, ktory wlasnie wyslal sysgnal // wait3 == wait4(0,...) while ((pid_tmp = wait4(0, &returnCode, 0, &timeData)) != (-1)) { for (int i = 0; i < maxproc; i++) { if (process[i].pid == pid_tmp) { process[i].timeProcSystem_us = timeData.ru_stime.tv_usec; process[i].timeProcUser_us = timeData.ru_utime.tv_usec; process[i].returnCode = returnCode; i = maxproc; } } } int *len_buff; fstream file_out; file_out.open("wynik_multifind.txt", ios::out); if (file_out.good() == true) { for (int i = 0; i < maxproc; ++i) { len_buff = (int *) (fileinmemory + process[i].shm_diff + process[i].shm_len - 8); file_out.write(process[i].shm_start, *len_buff); } file_out.close(); } for (int i = 0; i < maxproc; ++i) { cout << "*** Proces: [" << i << "], kod zakonczenia: " << (process[i].returnCode >> 8) << endl; cout << "Czas pracy procesu: " << (double) (process[i]. countTimeProcess_stop - process[i]. countTimeProcess_start) / sysconf(_SC_CLK_TCK) << "s" << endl; cout << "Czas procesora w trybie uzytkownika: " << setw(8) << (double) process[i].timeProcUser_us / CLOCKS_PER_SEC << "s" << endl; cout << "Czas procesora w trybie systemowym: " << setw(9) << (double) process[i].timeProcSystem_us / CLOCKS_PER_SEC << "s" << endl << endl; } int r = shmdt(fileinmemory); if (r == -1) { perror("Multifind: shmdt."); } r = shmctl(smid, IPC_RMID, NULL); if (r == -1) { perror("Multifind: shmCTL."); } cout << endl; return 0;}voidsygnal(int signo, siginfo_t * sigf, void *b){ for (int i = 0; i < maxproc; ++i) { if (process[i].pid == sigf->si_pid) { process[i].countTimeProcess_stop = times(&bufor); i = maxproc; } } end_main += 1;} |
***
Inne wpisy:
Oświetlenie miejsca pracy
Oświetlenie LED łazienki (małej)
Zużycie prądu przez suszarkę do ubrań i pralkę
Zużycie prądu przez urządzenia domowe i ich współczynnik mocy cos phi (cosφ)
Modernizacja oświetlenia głównego w dużym pokoju i przedpokoju
Oświetlenie LED łazienki (małej)
Zużycie prądu przez suszarkę do ubrań i pralkę
Zużycie prądu przez urządzenia domowe i ich współczynnik mocy cos phi (cosφ)
Modernizacja oświetlenia głównego w dużym pokoju i przedpokoju
Update: 2018.07.17
Create: 2018.07.17
Brak komentarzy:
Prześlij komentarz