/* gcc -g second_job.cpp -o second_job 考え方 (1)8時間労働、8時間睡眠、8時間余暇を基本として考える。 (2)8時間余暇の中には、通勤時間1.5時間 食事時間1.5時間が含まれるものとする (3)とすれば、残りの余暇5時間をどのような使い方をするのかが問題となる。 (4)十分な余暇は、基本的に正業のパフォーマンスを上げるものであるとする。 (4)余暇を使った副業は、収入になるものとする */ #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct person { double first_business_hour; double sleep_hour; double commute_time; double meal_time; double max_remain_time; double second_business_hour; double final_remain_time; double fb_fee; double sb_fee; double fatigue_func; double cost; struct person *prev; /* 前の構造体を示すポインタ */ struct person *next; /* 次の構造体を示すポインタ */ } PERSON; double min(double a, double b) { if (a > b) return b; else return a; } double diff(double a, double b) { if (a > b) return a - b; else return 0; } double fatigue_func(double time) { if (time < 1.0){ return 0.5; } else if ((time >= 1.0) && (time < 3.0)){ return (1.0 - 0.5)/(3.0 - 1.0) * (time - 1.0) + 0.5; } else { return 1.0; } } const double First_Business_hourly_fees = 2000; const double First_Business_extra_fees = First_Business_hourly_fees * 1.25; const double Second_Business_hourly_fees = 1000; int main() { srand(13); PERSON* first_p_person= (PERSON*)malloc(sizeof(PERSON)); PERSON* last_p_person= (PERSON*)malloc(sizeof(PERSON)); PERSON* p_prev_person = first_p_person; for (int i = 0; i < 100; i++){ PERSON* p_person= (PERSON*)malloc(sizeof(PERSON)); memset(p_person, 0, sizeof(PERSON)); //////// ポインタの貼り替え ////////// p_prev_person->next = p_person; p_person->next = last_p_person; p_person->prev = p_prev_person; p_prev_person = p_person; ////////////////////////////////////// p_person->first_business_hour = 8.0 + 2.0 * (double)rand()/RAND_MAX; // 8~10時間 p_person->first_business_hour = 8.0; // 8~10時間 p_person->sleep_hour = 7.0 + 1.0 * (1.0 - 2.0 * (double)rand()/RAND_MAX); // 6~8時間 p_person->commute_time = 1.0 + 0.5 * (1.0 - 2.0 * (double)rand()/RAND_MAX); // 0.5~1.5時間 p_person->meal_time = 1.0 + 0.5 * (1.0 - 2.0 * (double)rand()/RAND_MAX); // 0.5~1.5時間 p_person->max_remain_time = 24.0 - p_person->first_business_hour - p_person->sleep_hour - p_person->commute_time - p_person->meal_time; // 最悪でも3時間の、最良で9時間の余暇時間ができる #if 1 p_person->second_business_hour = p_person->max_remain_time * (double)rand()/RAND_MAX; //余暇の時間を適当に振る #else p_person->second_business_hour = 0; #endif p_person->final_remain_time = p_person->max_remain_time - p_person->second_business_hour; p_person->fb_fee = min(p_person->first_business_hour, 8.0) * First_Business_hourly_fees + diff(p_person->first_business_hour, 8.0) * First_Business_extra_fees; p_person->sb_fee = p_person->second_business_hour * Second_Business_hourly_fees; p_person->fatigue_func = fatigue_func(p_person->final_remain_time); p_person->cost = p_person->fb_fee * p_person->fatigue_func + p_person->sb_fee; //printf("%d:cost = %f\n", i, p_person->cost); } double total_cost = 0.0; PERSON* p_person = first_p_person->next; printf("本業時間,睡眠時間,通勤時間,食事時間,余暇時間,副業時間,残余暇時間,RATIO,収入\n"); while(p_person->next != last_p_person){ total_cost += p_person->cost; printf("%f,%f,%f,%f,%f,%f,%f,%f,%f\n", p_person->first_business_hour, p_person->sleep_hour, p_person->commute_time, p_person->meal_time, p_person->max_remain_time, p_person->second_business_hour, p_person->final_remain_time, p_person->fatigue_func, p_person->cost ); p_person = p_person->next; } printf("total cost = %f\n", total_cost); }
途中の状態のプロセスを凍らせてセーブするもの(らしい)
途中の状態のプロセスを凍らせてセーブするもの(らしい)
この説明が詳しい http://dmtcp.sourceforge.net/dmtcp-mug-17.pdf
プロセスの保存と復元によるGUIアプリケーションの起動高速化
http://oberon.nagaokaut.ac.jp/katsuk/papers/ipsj/10/IPSJ/pdf/arc/3L_7.pdf
/* mingw64でfork()を何とかしたい gcc -g fork.c -o fork (ちゃんと動いているのかどうか不明だけど) ちなみに、"コマンドプロント"だけだと、"ko"が出てこないので、 fork > dummy.txt みたいにしないと、稼動確認できないみたい ちなみにタスクマネージャで見る限り、2つのプロセスは動いているみたい gcc -g fork.c -o fork fork.c:81:7: warning: conflicting types for built-in function 'fork' pid_t fork(void) ^ fork.c: In function 'fork': fork.c:92:11: warning: assignment from incompatible pointer type clone_p = GetProcAddress(mod, "RtlCloneUserProcess"); という警告がでるが、良く分からんので、今は放置 */ /* * fork.c * Experimental fork() on Windows. Requires NT 6 subsystem or * newer. * * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * This software is provided 'as is' and without any warranty, express or * implied. In no event shall the authors be liable for any damages arising * from the use of this software. */ #define _WIN32_WINNT 0x0600 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winnt.h> #include <ntdef.h> #include <stdio.h> #include <errno.h> #include <process.h> #ifdef __MINGW32__ typedef struct _CLIENT_ID { PVOID UniqueProcess; PVOID UniqueThread; } CLIENT_ID, *PCLIENT_ID; typedef struct _SECTION_IMAGE_INFORMATION { PVOID EntryPoint; ULONG StackZeroBits; ULONG StackReserved; ULONG StackCommit; ULONG ImageSubsystem; WORD SubSystemVersionLow; WORD SubSystemVersionHigh; ULONG Unknown1; ULONG ImageCharacteristics; ULONG ImageMachineType; ULONG Unknown2[3]; } SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION; typedef struct _RTL_USER_PROCESS_INFORMATION { ULONG Size; HANDLE Process; HANDLE Thread; CLIENT_ID ClientId; SECTION_IMAGE_INFORMATION ImageInformation; } RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION; #define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED 0x00000001 #define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES 0x00000002 #define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE 0x00000004 #define RTL_CLONE_PARENT 0 #define RTL_CLONE_CHILD 297 #endif typedef NTSTATUS (*RtlCloneUserProcess_f) (ULONG ProcessFlags, PSECURITY_DESCRIPTOR ProcessSecurityDescriptor /* optional */, PSECURITY_DESCRIPTOR ThreadSecurityDescriptor /* optional */, HANDLE DebugPort /* optional */, PRTL_USER_PROCESS_INFORMATION ProcessInformation); pid_t fork(void) { HMODULE mod; RtlCloneUserProcess_f clone_p; RTL_USER_PROCESS_INFORMATION process_info; NTSTATUS result; mod = GetModuleHandle("ntdll.dll"); if (!mod) return -ENOSYS; clone_p = GetProcAddress(mod, "RtlCloneUserProcess"); if (clone_p == NULL) return -ENOSYS; /* lets do this */ result = clone_p(RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED | RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, NULL, NULL, NULL, &process_info); if (result == RTL_CLONE_PARENT) { HANDLE me = GetCurrentProcess(); pid_t child_pid; child_pid = GetProcessId(process_info.Process); ResumeThread(process_info.Thread); CloseHandle(process_info.Process); CloseHandle(process_info.Thread); return child_pid; } else if (result == RTL_CLONE_CHILD) { /* fix stdio */ AllocConsole(); return 0; } else return -1; /* NOTREACHED */ return -1; } #if 0 // #ifdef __TEST__ int main(int argc, const char *argv[]) { pid_t pid = fork(); printf("pid %d\n", pid); switch (pid) { case 0: { printf("parent %d\n", pid); FILE *f = fopen("forktest.dat", "w"); fprintf(f, "ok\n"); fclose(f); break; } default: printf("child %d\n", pid); int i = 0; while (i < 10000){ i++; } break; } } //#endif #endif #if 1 int main(int argc, char *argv[]) { int i,pid; int pid2; int status; // printf("---Fork test---\n"); pid = fork(); /*子プロセスの生成。戻り値 0:子プロセス -1:エラー 0以上:親プロセス */ printf("fork() : pid = %d\n" , pid); for(i = 0 ; i < 5 ; i++){ //my_sleep(1); /*一秒待機*/ Sleep(1000); pid2 = getpid(); printf("%d : %s %d %d\n" , i , pid > 0 ? "Oya:" : "Ko :" , pid2, pid); fflush(stdout); // これを省略すると、バラバラに出力されなくなる } //wait(&status); /*子プロセスが終了するのを待つ→wait()関数がない*/ return EXIT_SUCCESS; } #endif
/* ================================================ mingw64でfork(),waitpid(), kill()を何とかしたい ================================================ ●参照させて頂いたページ https://gist.github.com/Cr4sh/126d844c28a7fbfd25c6 http://7shi.hateblo.jp/entry/2012/06/19/213405 http://www.fireproject.jp/feature/c-language/process/fork-wait.html ●コンパイル: gcc -g fork2.cpp -o fork2 ●その他 「mingw64でfork()を何とかしたい」の後に読むと分かりやすいかも ちなみにWindowsのコマンドプロンプトではprintf()の表示がされない(理由不明)ので > fork2 > dummy.txt などとして確認すること。 */ /* * fork.c * Experimental fork() on Windows. Requires NT 6 subsystem or * newer. * * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * This software is provided 'as is' and without any warranty, express or * implied. In no event shall the authors be liable for any damages arising * from the use of this software. */ #define _WIN32_WINNT 0x0600 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winnt.h> #include <ntdef.h> #include <stdio.h> #include <errno.h> #include <process.h> #define CHILD_NUM 10 #define WNOHANG 1 /* dont hang in wait */ // ここではコンパイル通す為のダミー値 #ifdef __MINGW32__ typedef struct _CLIENT_ID { PVOID UniqueProcess; PVOID UniqueThread; } CLIENT_ID, *PCLIENT_ID; typedef struct _SECTION_IMAGE_INFORMATION { PVOID EntryPoint; ULONG StackZeroBits; ULONG StackReserved; ULONG StackCommit; ULONG ImageSubsystem; WORD SubSystemVersionLow; WORD SubSystemVersionHigh; ULONG Unknown1; ULONG ImageCharacteristics; ULONG ImageMachineType; ULONG Unknown2[3]; } SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION; typedef struct _RTL_USER_PROCESS_INFORMATION { ULONG Size; HANDLE Process; HANDLE Thread; CLIENT_ID ClientId; SECTION_IMAGE_INFORMATION ImageInformation; } RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION; #define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED 0x00000001 #define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES 0x00000002 #define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE 0x00000004 #define RTL_CLONE_PARENT 0 #define RTL_CLONE_CHILD 297 #endif typedef NTSTATUS (*RtlCloneUserProcess_f) (ULONG ProcessFlags, PSECURITY_DESCRIPTOR ProcessSecurityDescriptor /* optional */, PSECURITY_DESCRIPTOR ThreadSecurityDescriptor /* optional */, HANDLE DebugPort /* optional */, PRTL_USER_PROCESS_INFORMATION ProcessInformation); pid_t fork(void) { HMODULE mod; RtlCloneUserProcess_f clone_p; RTL_USER_PROCESS_INFORMATION process_info; NTSTATUS result; mod = GetModuleHandle("ntdll.dll"); if (!mod) return -ENOSYS; //clone_p = GetProcAddress(mod, "RtlCloneUserProcess"); // Ebata clone_p = (RtlCloneUserProcess_f)GetProcAddress(mod, "RtlCloneUserProcess"); if (clone_p == NULL) return -ENOSYS; /* lets do this */ result = clone_p(RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED | RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, NULL, NULL, NULL, &process_info); if (result == RTL_CLONE_PARENT) { HANDLE me = GetCurrentProcess(); pid_t child_pid; child_pid = GetProcessId(process_info.Process); ResumeThread(process_info.Thread); CloseHandle(process_info.Process); CloseHandle(process_info.Thread); return child_pid; } else if (result == RTL_CLONE_CHILD) { /* fix stdio */ AllocConsole(); return 0; } else return -1; /* NOTREACHED */ return -1; } int kill(pid_t pid, int sig) { int ret; HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); ret = TerminateProcess(h, 0) ? 0 : -1; CloseHandle(h); return ret; } #if 0 int waitpid(pid_t pid, int *stat_loc, int options) { int i = 1; return _cwait(stat_loc, pid, WAIT_CHILD); } #endif int waitpid(pid_t pid, DWORD dwMilliseconds) // Ebata's original waitpid() { HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); // WaitForSingleObject(h, INFINITE); int ret = WaitForSingleObject(h, dwMilliseconds); CloseHandle(h); return ret; } int main(void){ pid_t result_pid = fork(); if (result_pid == 0){ // 子プロセス printf("Child process started.\n"); printf("Wait 10 seconds.\n"); printf("result_pid = %d child process.\tpid = %d\n",result_pid,getpid()); fflush(stdout); Sleep(10000); // 10秒くらいの生存期間 fprintf(stdout,"Child process ended.\n"); fflush(stdout); } else{ // 親プロセス printf("Parents process started.\n"); fflush(stdout); // 親プロセスの方には、子プロセスのIDが入るので、それを監視する waitpid(result_pid, INFINITE); // 子プロセス(1つのみ)が終了するまで止まる //waitpid(result_pid, 100); // 100msのみ停止 fprintf(stdout,"Parent process ended.\n"); fflush(stdout); } return 0; }
/* ================================================ mingw64でfork(),waitpid(), kill()を何とかしたい ================================================ ●参照させて頂いたページ https://gist.github.com/Cr4sh/126d844c28a7fbfd25c6 http://7shi.hateblo.jp/entry/2012/06/19/213405 http://www.fireproject.jp/feature/c-language/process/fork-wait.html ●コンパイル: gcc -c fork.cpp ●その他 「mingw64でfork()を何とかしたい」の後に読むと分かりやすいかも ちなみにWindowsのコマンドプロンプトではprintf()の表示がされない(理由不明)ので > fork2 > dummy.txt などとして確認すること。 */ /* * fork.c * Experimental fork() on Windows. Requires NT 6 subsystem or * newer. * * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * This software is provided 'as is' and without any warranty, express or * implied. In no event shall the authors be liable for any damages arising * from the use of this software. */ #define _WIN32_WINNT 0x0600 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winnt.h> #include <ntdef.h> #include <stdio.h> #include <errno.h> #include <process.h> #ifdef __MINGW32__ typedef struct _CLIENT_ID { PVOID UniqueProcess; PVOID UniqueThread; } CLIENT_ID, *PCLIENT_ID; typedef struct _SECTION_IMAGE_INFORMATION { PVOID EntryPoint; ULONG StackZeroBits; ULONG StackReserved; ULONG StackCommit; ULONG ImageSubsystem; WORD SubSystemVersionLow; WORD SubSystemVersionHigh; ULONG Unknown1; ULONG ImageCharacteristics; ULONG ImageMachineType; ULONG Unknown2[3]; } SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION; typedef struct _RTL_USER_PROCESS_INFORMATION { ULONG Size; HANDLE Process; HANDLE Thread; CLIENT_ID ClientId; SECTION_IMAGE_INFORMATION ImageInformation; } RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION; #define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED 0x00000001 #define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES 0x00000002 #define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE 0x00000004 #define RTL_CLONE_PARENT 0 #define RTL_CLONE_CHILD 297 #endif typedef NTSTATUS (*RtlCloneUserProcess_f) (ULONG ProcessFlags, PSECURITY_DESCRIPTOR ProcessSecurityDescriptor /* optional */, PSECURITY_DESCRIPTOR ThreadSecurityDescriptor /* optional */, HANDLE DebugPort /* optional */, PRTL_USER_PROCESS_INFORMATION ProcessInformation); pid_t fork(void) { HMODULE mod; RtlCloneUserProcess_f clone_p; RTL_USER_PROCESS_INFORMATION process_info; NTSTATUS result; mod = GetModuleHandle("ntdll.dll"); if (!mod) return -ENOSYS; //clone_p = GetProcAddress(mod, "RtlCloneUserProcess"); // Ebata clone_p = (RtlCloneUserProcess_f)GetProcAddress(mod, "RtlCloneUserProcess"); if (clone_p == NULL) return -ENOSYS; /* lets do this */ result = clone_p(RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED | RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, NULL, NULL, NULL, &process_info); if (result == RTL_CLONE_PARENT) { HANDLE me = GetCurrentProcess(); pid_t child_pid; child_pid = GetProcessId(process_info.Process); ResumeThread(process_info.Thread); CloseHandle(process_info.Process); CloseHandle(process_info.Thread); return child_pid; } else if (result == RTL_CLONE_CHILD) { /* fix stdio */ AllocConsole(); return 0; } else return -1; /* NOTREACHED */ return -1; } int kill(pid_t pid, int sig) { int ret; HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); ret = TerminateProcess(h, 0) ? 0 : -1; CloseHandle(h); return ret; } #if 0 int waitpid(pid_t pid, int *stat_loc, int options) { int i = 1; return _cwait(stat_loc, pid, WAIT_CHILD); } #endif int waitpid(pid_t pid, DWORD dwMilliseconds) // Ebata's original waitpid() { HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); // WaitForSingleObject(h, INFINITE); int ret = WaitForSingleObject(h, dwMilliseconds); CloseHandle(h); return ret; } #if 0 // サンプルプログラム int main(void){ pid_t result_pid = fork(); if (result_pid == 0){ // 子プロセス printf("Child process started.\n"); printf("Wait 10 seconds.\n"); printf("result_pid = %d child process.\tpid = %d\n",result_pid,getpid()); fflush(stdout); Sleep(10000); // 10秒くらいの生存期間 fprintf(stdout,"Child process ended.\n"); fflush(stdout); } else{ // 親プロセス printf("Parents process started.\n"); fflush(stdout); // 親プロセスの方には、子プロセスのIDが入るので、それを監視する waitpid(result_pid, INFINITE); // 子プロセス(1つのみ)が終了するまで止まる //waitpid(result_pid, 100); // 100msのみ停止 fprintf(stdout,"Parent process ended.\n"); fflush(stdout); } return 0; } #endif // サンプルプログラム ========================================================== /* シュタインズゲートの「タイムリープ」をコーディングするとこんな感じ gcc -c fork_test.cpp gcc -g fork.cpp fork_test.cpp -o fork_test */ #include <windows.h> #include <stdio.h> #include <process.h> extern pid_t fork(void); extern int waitpid(pid_t pid, DWORD dwMilliseconds); // Ebata's original waitpid() extern int kill(pid_t pid, int sig); int main(void){ pid_t result_pid = -1; // fork()が吐き出さない値をダミーに入れておく int init_i = -1; for (int i = 0; i < 100; i++){ if (i == 17){ // iが17になった時に、子プロセスを起動 result_pid = fork(); init_i = i ; } if (result_pid == 0){ // 子プロセス printf("c:\t%d\n", i); fflush(stdout); if (i > init_i + 50){ // 「岡部、50回先の未来に行く」 exit(0); // 子プロセスの強制終了 } } else { waitpid(result_pid, INFINITE); // 子プロセス(1つのみ)が終了するまで止まる printf("p:%d\n", i);// 「岡部、リーディングシュタイナー発動(記憶を維持したまま、50回前の過去にタイムリープ」 fflush(stdout); } } }