끝나지만 끝나지 않는 프로그램 [닫힘]


35

완료되면 다시 시작되는 프로그램을 작성하십시오.

동시에 실행중인 프로그램의 인스턴스는 두 개 이상 없어야합니다. 아주 작은 순간조차도.

주기 동안 사용자가 수동으로 시작한 인스턴스는 무시해도됩니다. 그러나 코드는 재시작 사이클에서 수행해서는 안됩니다.

프로그램이 다시 시작된다는 보장이있는 한 일정 시간이 지나면 프로그램을 시작할 수 있습니다.

주기를 중지하는 유일한 방법은 프로세스를 종료하는 것입니다.

솔루션은 환경을 다시 시작하지 않아야합니다 (프로그램이 실행되고 OS, 시스템, VM, 셸 포함). 프로그램 만 다시 시작할 수 있습니다.


11
이게 exec리눅스에서하는 것 아닌가요?
mniip

11
지금 작성하는 것이 조금 게으르지 만 제출 한 내용은 다음과 같습니다 (Windows의 경우). "프로그램이 시작될 때 부팅되도록 레지스트리를 편집하십시오. 실행 shutdown -r -t 0 -f"
Cruncher

3
프로세스를 종료해도 사이클이 종료되지는 않습니다.
microbian

19
방금 깨달았습니다. 바이러스를 작성하고 방법을 모른다면 1) StackOverflow로 가서 방법을 물어보십시오. 모두로부터 미움을 받으면 아마도 질문이 끝날 것입니다. 또는 2) 코드 골프로 가서 다른 사람들에게 어떻게하는지 물어보십시오. 선택할 수있는 몇 가지 창의적인 답변을 얻으십시오. 질문은 네트워크 전체의 "핫"목록에 올라온 인기입니다. 무 아하 하하하
rumtscho

5
@rumtscho 아시다시피, 그것은 좋은 일반적인 전략입니다. 다음 과제로, 링크 된 문서의 모든 요구 사항을 충족하는 책상 위에 앉아있는 프로토 타입 장치에 가장 작은 펌웨어를 작성할 수있는 사람을 보자. 이를 강화하려면 월요일 오전 8 시까 지 완료해야합니다. 가기!
Jason C

답변:


50

배쉬 스크립트, 3 문자 (가장 논란의 여지가 있지만 가장 우아하고 아마도 가장 우아합니다)

$0&

백그라운드에 새로운 인스턴스를 배치하고 (새 프로세스) 종료합니다. 새 인스턴스는 이전 인스턴스가 완료 될 때까지 스케줄러 실행 큐에 남아있을 것입니다.

경고 kill-PID가 지속적으로 변경되므로이 작업 을 수행하기가 어렵습니다 . 스크립트 파일의 이름을 임시로 바꾸는 것이주기를 중단시키는 가장 간단한 방법 일 것입니다.

단일 코어 시스템이 가정됩니다. 물론 이것은 최신 베어 메탈 하드웨어의 Linux에서는 현실적이지 않지만 VM에서 실행할 때 쉽게 구성 할 수 있습니다. 우리는 아마도을 사용하여 비슷한 트릭을 얻을 수는 taskset있지만 3-char 솔루션의 영향을 줄입니다.

이 답변은 "실행 중"이라는 특정 의미를 적용한다는 점에서 규칙을 약간 구부립니다. 새로운 프로세스가 완료 fork()되고 이전 프로세스가 여전히 존재하는 순간이있을 것입니다. 즉, 하나 이상의 PID를 관찰하는 것이 가능할 수 있습니다. 그러나 새 프로세스는 Linux 스케줄러 실행 큐에 배치되어 CPU주기를 기다리는 동안 기존 프로세스는 계속 실행됩니다. 이 시점에서 기존 프로세스에서 수행해야 할 모든 작업은 bash그 자체 exit()입니다. 현재 시간 조각 / 스케줄러 양자가 수행되기 전에 완료 될 것이라고 확신합니다. 지원 증거는 bash내 VM에서 2ms 내에 시작 및 종료 된다는 사실입니다 .

$ 시간 배쉬 -c :

실제 0m0.002s
사용자 0m0.000s
시스템 0m0.000s
$ 

이전 프로세스가 완료 될 때까지 새 프로세스가 실제로 실행되지 않는다는 추가 증거를 strace출력 에서 볼 수 있습니다 .

strace -f -tt -o forever.strace bash -c ./forever.sh 

출력에서 원래 프로세스에 PID 6929가 있음을 알 수 있습니다. fork()호출 (실제로 clone())은 새 PID 6930을 리턴합니다.이 시점에서 2 개의 PID가 있지만 현재 6929 만 실행 중입니다.

6929 12 : 11 : 01.031398 clone (child_stack = 0, flags = CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD, child_tidptr = 0x7f2f83ac49d0) = 6930
6929 12 : 11 : 01.031484 rt_sigprocmask (SIG_SETMASK, [], NULL, 8) = 0
6929 12 : 11 : 01.031531 rt_sigprocmask (SIG_BLOCK, [CHLD], [], 8) = 0
6929 12 : 11 : 01.031577 rt_sigprocmask (SIG_BLOCK, [CHLD], [CHLD], 8) = 0
6929 12 : 11 : 01.031608 rt_sigprocmask (SIG_SETMASK, [CHLD], NULL, 8) = 0
6929 12 : 11 : 01.031636 rt_sigprocmask (SIG_BLOCK, [CHLD], [CHLD], 8) = 0
6929 12 : 11 : 01.031665 rt_sigprocmask (SIG_SETMASK, [CHLD], NULL, 8) = 0
6929 12 : 11 : 01.031692 rt_sigprocmask (SIG_BLOCK, [CHLD], [CHLD], 8) = 0
6929 12 : 11 : 01.031726 rt_sigprocmask (SIG_SETMASK, [CHLD], NULL, 8) = 0
6929 12 : 11 : 01.031757 rt_sigprocmask (SIG_SETMASK, [], NULL, 8) = 0
6929 12 : 11 : 01.031803 rt_sigprocmask (SIG_BLOCK, NULL, [], 8) = 0
6929 12 : 11 : 01.031841 읽기 (255, "", 4) = 0
6929 12 : 11 : 01.031907 exit_group (0) =?
6930 12 : 11 : 01.032016 닫기 (255) = 0
6930 12 : 11 : 01.032052 rt_sigprocmask (SIG_SETMASK, [], NULL, 8) = 0

strace여기에 전체 출력.

6929는 6929가 완전히 완료 될 때까지 시스템 호출을 발행하지 않음을 알 수 있습니다. 6929가 완료 될 때까지 6930이 전혀 실행되지 않는다는 것을 의미하는 것으로 가정하는 것이 합리적입니다. perf유틸리티는이를 입증 할 수있는 궁극적 인 방법이 될 것입니다.


21
"레스토랑 ... 그런 다음 종료", 둘 이상의 인스턴스가 동시에 실행되고 있습니까?
microbian

4
"... 단일 코어에"-예, 나도 그렇게 생각합니다. 많은 코어에서 많은 것을 볼 수있을 것입니다.
blabla999

3
이것이 code-golf로 태그 되었다면, 이것은 확실히 이길 것입니다! +1
John Odom

3
@DigitalTrauma 배쉬가 종료되는 데 걸리는 시간에 대해 큰 가정을하고 있습니다. top은 아무 것도 말해주지 않습니다-몇 초마다 한 번만 업데이트되지만 초당 많은 프로세스가 생성됩니다.
David Richerby

2
@DavidRicherby-당신은 절대적으로 맞습니다- top여기에 사용하기에 적합한 도구가 아닙니다. 그러나 나는 time bash -c :Ubuntu VM에서 2ms 밖에 걸리지 않으므로 bash스케줄링 퀀텀이 완료되기 전에 종료를 완료 한다고 부당하다고 생각하지 않습니다 .
Digital Trauma

26

해결책 1

PHP, 32 자

헤더를 보낸 다음 중지합니다. 3 초 후 페이지가 다시로드됩니다.

a.php 파일

header("Refresh: 3; url=a.php");

헤더를 보내기 전에 페이지 실행을 종료하거나 브라우저를 종료하여 중지 할 수 있습니다.


해결책 2

PHP, 2 페이지

두 파일이 서로 다른 두 프로그램을 고려해 봅시다. 두 파일은 같은 폴더에 있습니다.

a.php 파일

header("Location:b.php");

파일 b.php

header("Location:a.php");

헤더를 보내기 전에 페이지 중 하나를 종료하면 프로그램이 종료됩니다 (브라우저 작동 중지).

여기 같은 프로그램이 있습니다

ASP.NET

파일 a.aspx

Response.Redirect("b.aspx")

파일 b.aspx

Response.Redirect("a.aspx")

1
좋은 해결책입니다. 나는 다른 사람들이 이것과는 다른 대답을하기를 바랍니다. 그래서 제가 인기 콘테스트로 계속했습니다.
microbian

귀하의 3 초 재로드 답변이 유효한지 여부에 관계없이 PHP 전문가에게 맡깁니다. 나는 PHP가 아닌 브라우저를 기다리는 브라우저이기 때문에 유효 할 것이라고 생각합니다 (나는 전문가가 아닙니다).
microbian

1
기술적으로 PHP는 웹 서버의 모듈로 실행되고 웹 서버는 다시 시작되지 않지만 .php 파일을 스크립트로 간주하고 스크립트가 여러 번 실행되는 경우 유효하다고 생각합니다.
TwiNight

@TwiNight 피드백 주셔서 감사합니다, 감사합니다 :)
Vereos

2
두 번째 솔루션의 경우 브라우저가 리디렉션 루프를 감지하고 자체적으로 중지하지 않습니까? thedan1984.com/wp-content/uploads/2012/02/…
Ajedi32

19

echo $PWD/$0 | at tomorrow

이것은 모든 Posix 호환 시스템에서 작동합니다.

파일을 삭제하려면 파일을 삭제하거나을 사용하십시오 atrm.


17

세게 때리다

exec "$0"

exec새로운 프로세스를 생성하지 않고 쉘을 대체합니다. 이렇게하면 두 번째 인스턴스가 없어야합니다.


1
더 넣어 ~/.bash_profile!
yegle

@yegle : $0-bash언제 .bash_profile소스되었으므로 구문 오류가 발생합니다.
Dennis

죄송합니다.
yegle

exec ${0##-}in ~/.bash_profileworks :-)
yegle

14

Windows 작업 스케줄러 (기본)

C ++. COM 프로그래밍의 악몽. 모든 도전 요구 사항을 충족합니다.

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <taskschd.h>
#include <comutil.h>

#pragma comment(lib, "taskschd.lib")
#pragma comment(lib, "comsuppw.lib")    

static void timeplus (int seconds, char timestr[30]);


int main () {

    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    CoInitializeSecurity(NULL, -1, NULL, NULL,
        RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
        RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);

    const char *name = "Restarter";

    char path[MAX_PATH + 1];
    GetModuleFileNameA(NULL, path, sizeof(path));
    path[sizeof(path) - 1] = 0; // workaround for xp

    ITaskService *taskman;
    CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER,
        IID_ITaskService, (void **)&taskman);

    taskman->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());

    ITaskFolder *root;
    taskman->GetFolder(_bstr_t("\\"), &root);

    // Delete the task.
    root->DeleteTask(_bstr_t(name), 0);

    // pause for 5 seconds to give user a chance to kill the cycle
    fprintf(stderr, "If you want to kill the program, close this window now.\n");
    Sleep(5000);
    fprintf(stderr, "Sorry, time's up, maybe next time.\n");

    // Create the task for 5 seconds from now.
    ITaskDefinition *task;
    taskman->NewTask(0, &task);

    IPrincipal *principal;
    task->get_Principal(&principal);
    principal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN);

    ITaskSettings *settings;
    task->get_Settings(&settings);
    settings->put_StartWhenAvailable(VARIANT_TRUE);
    settings->put_DisallowStartIfOnBatteries(VARIANT_FALSE);
    settings->put_StopIfGoingOnBatteries(VARIANT_FALSE);

    ITriggerCollection *triggers;
    task->get_Triggers(&triggers);

    ITrigger *trigger;
    triggers->Create(TASK_TRIGGER_TIME, &trigger);

    char when[30];
    ITimeTrigger *trigger_time;
    trigger->QueryInterface(IID_ITimeTrigger, (void **)&trigger_time);
    trigger_time->put_Id(_bstr_t("TimeTrigger"));
    timeplus(10, when);
    trigger_time->put_StartBoundary(_bstr_t(when));
    timeplus(300, when);
    trigger_time->put_EndBoundary(_bstr_t(when));

    IActionCollection *actions;
    task->get_Actions(&actions);

    IAction *action;
    actions->Create(TASK_ACTION_EXEC, &action);

    IExecAction *action_exec;
    action->QueryInterface(IID_IExecAction, (void **)&action_exec);
    action_exec->put_Path(_bstr_t(path));

    IRegisteredTask *regtask;
    root->RegisterTaskDefinition(_bstr_t(name), task,
        TASK_CREATE_OR_UPDATE, _variant_t(), _variant_t(),
        TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(""),
        &regtask);

    regtask->Release();
    action_exec->Release();
    actions->Release();
    trigger_time->Release();
    trigger->Release();
    triggers->Release();
    settings->Release();
    principal->Release();
    task->Release();
    root->Release();
    taskman->Release();
    CoUninitialize();

}


// outputs current utc time + given number of seconds as 
// a string of the form YYYY-MM-DDTHH:MM:SSZ
static void timeplus (int seconds, char timestr[30]) {

    SYSTEMTIME when;
    FILETIME whenf;
    LARGE_INTEGER tempval;

    GetSystemTimeAsFileTime(&whenf);
    tempval.HighPart = whenf.dwHighDateTime;
    tempval.LowPart = whenf.dwLowDateTime;
    tempval.QuadPart += seconds * 10000000LL; // 100 nanosecond units
    whenf.dwHighDateTime = tempval.HighPart;
    whenf.dwLowDateTime = tempval.LowPart;
    FileTimeToSystemTime(&whenf, &when);

    sprintf(timestr, "%04hu-%02hu-%02huT%02hu:%02hu:%02huZ",
        when.wYear, when.wMonth, when.wDay,
        when.wHour, when.wMinute, when.wSecond);

}

MSVC (또는 모든 종속성이있는 경우 MinGW GCC)로 컴파일하십시오.

프로그램은 Windows 작업 스케줄러를 사용하여 일회성 작업을 시작하고 5 초 후에 시작되도록 등록합니다 (제어판-> 관리 도구-> 작업 스케줄러를 보려면 작업 이름이 "다시 시작"). 프로그램은 작업을 생성하기 전에 프로그램을 종료 할 수있는 5 초 동안 일시 중지됩니다.

도전 과제 :

  • 완료되면 다시 시작됩니다. 예. 작업은 프로그램 종료 직전에 예약됩니다.

  • 동시에 실행되는 프로그램의 인스턴스는 두 개 이상입니다. 예. 프로그램이 완전히 종료되고 5 초 동안 실행되지 않습니다. 스케줄러에 의해 시작됩니다.

  • 주기 동안 사용자가 수동으로 시작한 인스턴스는 무시해도됩니다. 예, 일정한 작업 이름을 사용하는 부작용으로 그렇습니다.

  • 다시 시작하는 것이 보장되는 한. 예, 작업 스케줄러가 실행중인 경우 (표준 Windows 구성에 있음).

  • 주기를 중지하는 유일한 방법은 프로세스를 종료하는 것입니다. 예, 5 초 동안 프로세스가 종료되는 동안 프로세스가 종료 될 수 있습니다. 프로그램은 5 초 지연 이전에 작업을 삭제하며이 시점에서 작업을 종료하면 스케줄러에 흩어진 작업이 남지 않습니다.

  • 솔루션을 다시 시작하면 안됩니다 . 예.

그건 그렇고, Windows 응용 프로그램이 왜 그렇게 불안정한 지 궁금해하는 사람이 있다면 (.NET 및 C #이 출현하기 전에) 이것이 이유 중 하나입니다. 프로그래머가 조금이라도 조금 게으른 경우 (위의 코드는 매우 게으름) 필요한 오류 처리량 (내가 포함 했음), 리소스 관리 및 자세한 정보는 오류가 발생하기 쉬운 상황을 설정합니다.

훨씬 쉽고 짧은 대안은 schtasks.exe를 호출하는 것입니다. .BAT 스크립트버전을 제출 했습니다 .


13

BBC BASIC-스노우 패트롤에 대한 찬사

bbcbasic.co.uk의 에뮬레이터

이것은 조금 다릅니다. 노래 "Run"의 구절을 인쇄하고 코드의 아르페지오를 연주하여 노래를 부를 수 있습니다. 실행 명령 (및 프로그램의 마지막 줄)은 물론 RUN이라는 사실에서 영감을 얻었습니다.

프로그램 시작시 모든 변수가 지워 지므로 다음 번 인쇄 할 구절을 결정하기 위해 이전 반복에서 남은 화면 색상이 사용됩니다.

    5 C=POINT(0,0) MOD 4
   10 COLOUR 129+C
   15 CLS
   20 RESTORE 110+C
   25 READ A$
   30 PRINT A$
   35 FORK = 1 TO 4
   40   RESTORE K+100
   45   READ P
   50   FORM= 1 TO 8
   55     SOUND 1,-15,P,7
   60     SOUND 1,-15,P-20,7
   65   NEXT
   70 NEXT
  101 DATA 100
  102 DATA 128
  103 DATA 136
  104 DATA 120
  110 DATA Light up light up - As if you have a choice - Even if you can not hear my voice - I'll be right beside you dear.
  111 DATA Louder louder - And we'll run for our lives - I can hardly speak - I understand - Why you can't raise your voice to say.
  112 DATA Slower Slower - We dont have time for that - All I want is to find an easier way - To get out of our little heads.
  113 DATA Have heart my dear - We're bound to be afraid - Even if its just for a few days - Makin' up for all of this mess.
  120 RUN

출력 (4 가지 스크린 샷의 몽타주)

여기에 이미지 설명을 입력하십시오


"공유 메모리"대안으로 컬러 솔루션에 +1.
Johannes H.

11

HTML / 자바 스크립트 :

<form /><script>document.forms[0].submit()</script>

이 코드는 실행중인 페이지의 삭제를 트리거 한 다음 브라우저가 페이지를 새로로드 할 때 다른 인스턴스 자체를 재생성합니다.

AFAIK, 유일한 방법은 페이지가 실행중인 탭을 죽이는 것입니다.

편집 : 인기있는 요청에 따라 유효한 HTML5 코드 :

<!doctype html><meta charset=utf-8><title> </title><form></form>
<script>document.forms[0].submit()</script>

@JasonC 동의하지 않습니다. 합리적인 페이지는 사양을 준수해야한다고 생각하지만 인기 콘테스트 는 합리적이어야합니까? : D +1, 나는 이것을 정말로 좋아합니다.
yo '

10

기음

이 프로그램은 많은 맬웨어처럼 작동합니다. 닫히기 전에 / tmp 디렉토리에 쉘 스크립트를 작성합니다. 쉘 스크립트를 시작하여 포크하여 원래 프로그램을 닫고 원래 PID를 취소 할 수 있습니다. 짧은 시간 (2 초) 후에 쉘 스크립트는 프로그램으로 새로운 프로세스를 시작합니다. 간결하게하기 위해 프로그램 위치는 '/ tmp / neverend /'로 고정되어 있습니다.

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

void rebirth(){
    char t[] = "/tmp/pawnXXXXXX";
    char* pawnfile = mktemp(t);
    if(pawnfile){
        int fd = open(pawnfile, O_RDWR|O_CREAT);
        const char msg[]="sleep 2\n/tmp/neverend\n";
        if(fd>0){
            int n = write(fd, msg, sizeof(msg));
            close(fd);
            pid_t pid = fork();
            if(pid==0){
                char* args[3] = {"bash", pawnfile, NULL};
                execvp(args[0], args);
            }
        }
    }
}

int main(int argc, char* argv[]){
    printf("Starting %s\n", argv[0]);
    atexit(rebirth);
    printf("Exiting %s\n", argv[0]);
}

한 번에 하나의 '절대'프로세스 만 실행됩니다. 각각의 새로운 프로세스는 새로운 PID를 얻습니다. 이를 제거하는 가장 쉬운 방법은 실행 파일을 삭제하는 것입니다. 좀 더 악성으로 만들고 싶다면 언제든지 실행 파일과 스크립트를 모두 복사하여 프로그램의 디스크에 여러 복사본이 있는지 확인할 수 있습니다.


1
더 혁신적인 답변을 기대하고 있습니다. '보충 프로그램'에 대한 질문은 의견을 참조하십시오. 나에게 보충 프로그램은 단지 당신의 프로그램의 일부입니다.
microbian

4
분기는 서로 다른 작업을 수행하더라도 프로세스의 두 인스턴스가 동시에 실행됨을 의미합니다.
Barry Fruitman

그러나 @BarryFruitman은 실제로 두 개의 다른 실행 파일을 사용하여 피할 수 있습니다. 그때는 유효하지만 덜 우아합니다.
Johannes H.

system()규칙이 포크 + 실행을 /bin/sh보조 프로그램으로 계산하지 않으면 사용할 수 있다고 가정합니다 .
Jason C

10

`perl -e"kill 9,$$"|perl $0`

스크립트는 시스템 명령을 실행하여 자체를 종료하고 결과를 다른 자체 인스턴스로 파이프합니다. 플랫폼 간 이유로 Perl 인터프리터가 킬링에 사용됩니다.

스크립트를 삭제하여 광기를 중지하십시오.


7

아타리 8 비트 기본

1L.:R.

토큰 화 :

1 LIST : RUN

내부적으로 내부 구조를 지우고 목록에서 다시 실행하기 전에 본질적으로 프로그램을 삭제합니다.

이것은 기본적으로 다음과 다릅니다.

1L.:G.1

어느 토큰 화 :

1 LIST : GOTO 1

이것은 기본 무한 루프입니다. 당신이 그들을 실행할 때, 당신은 속도의 차이를 볼 수 있습니다 (먼저 느립니다).


프로그램 실행 중 "목록"이 내부 구조를 지우는 이유는 확실하지 않습니다. 나는 Atari가 키보드 버퍼를 가지고 있다고 생각한다. 그래서 프로그램을 나열하고, 그것을 실행하기 위해 키 스트로크를 채우고, 커서를 "재 입력"하기 위해 "새로"할 수있다.
supercat

@supercat-LIST는하지 않습니다.

이 논리에 의해 "LIST"를 생략 할 수 있습니다. 반면에 프로그램이 캐리지 리턴이 적은 키보드 버퍼를 채우면 "NEW"다음에 프로그램과 "RUN"을 화면 오른쪽 지점에 놓고 커서를 집어 넣고 종료하면 실제로 자체적으로 지워집니다. 자동으로 다시 입력하십시오.
supercat

@supercat- LIST이 없으면 실행되지 않습니다. LIST입력이 가장 짧기 때문에 선택했습니다 L.. 나는 그것을 키보드 버퍼에 넣는 아이디어를 좋아한다. 확실히 짧다!

Commodore 머신과 같은 Atari가 화면에서 텍스트를 읽는다는 것을 정확하게 기억하고 Return있습니까? 키보드 버퍼는 얼마나 큽니까? VIC-20 및 C64에서는 10 바이트입니다. 키보드 버퍼를로드하기에 충분한 찌르기를 수행하는 프로그램은 아마도 키보드 버퍼에 맞지 않을 수도 있지만 화면에 변경 사항을 인쇄 RUN하고 Return키를 몇 번 눌러 자신을 수정하는 프로그램을 작성했습니다 . 이러한 것들이 64 줄에서 특히 유용했다. 왜냐하면 INAtari가 프로그램에 라인을 병합하기위한 [IIRC] 명령 이 없기 때문 이다.
supercat

5

z / OS를 실행하는 IBM 메인 프레임에서 데이터 세트 (파일)를 다른 데이터 세트 (파일)에 복사하는 유틸리티를 실행합니다. 입력은 제출하기 위해 제출 한 JCL (Job Control Language)의 소스입니다. 출력은 내부 리더 (INTRDR)입니다. 또한 시스템이 여러 개의 동일한 작업 이름을 실행할 수 없도록해야합니다. 초기자가 하나만있는 작업 클래스를 사용하는 것이 좋습니다 (JOB가 일괄 적으로 실행될 수있는 위치).

관련된 z / OS에 PID가 없으므로 챌린지 세트에 실패합니다.

배출 및 / 또는 세척을 통해 프로세스를 중단합니다. 배수구 및 / 또는 세척, 맹세, 발 차기, 웜 스타트 시도 및 마지막으로 콜드 스타트 ​​또는 Big Red 버튼을 눌렀을 때 (프로그래머 촬영) 문제가 발생한 경우.

나는 길을 과장했을 수도 있지만 직장에서 이것을 시도하지 마십시오 ...

SORT를 사용한 예. JOB 카드에 대한 자세한 내용은 사이트에 따라 다릅니다. 사이트 정책은 INTRDR의 사용을 금지하거나 금지 할 수 있습니다. INTRDR을 사용하려면 특정 클래스가 필요할 수 있습니다. 사이트 정책에 따라 사용 금지 된 경우 골판지 상자에 걸을 때 소지품을 가져 가지 않으려면 사용 하지 마십시오 .

INTRDR은 잘 사용되지만 이 목적으로 사용하지 마십시오 . 당신은 당신의 상자를 얻을 수있는 기회조차 없습니다.

//jobname JOB rest is to your site standards
//* 
//STEP0100 EXEC PGM=SORT 
//SYSOUT   DD SYSOUT=* 
//SORTOUT  DD SYSOUT=(,INTRDR) minimum required, site may require more 
//SYSIN    DD * 
  OPTION COPY 
//SORTIN   DD DISP=SHR,DSN=YOUR.LIBRARY.WITHJOB(JOBMEMBR) 

다른 유틸리티도 사용할 수 있습니다. 빠른 프로그램도 쉽게 할 수 있습니다. 파일을 읽고 파일을 쓰십시오.

이 잘못된 예를 보려면 http://ibmmainframes.com/viewtopic.php?p=282414#282414를 시도하십시오.

데이터 세트를 복사하는 전통적인 방법은 ugoren이 주석에서 언급 한 것처럼 IBM 유틸리티 IEBGENER를 사용하는 것입니다.

그러나 요즘 많은 사이트에서 IEBGENER가 ICEGENER에 "별칭"되어 있습니다. ICEGENER는 가능하면 IBM의 DFSORT (또는 라이벌 SyncSort)를 사용하여 사본을 작성합니다. SORT 제품은 IEBGENER보다 IO에 훨씬 더 최적화되어 있기 때문입니다.

SORT를 사용하여 중개인을 잘라 내고 있습니다.

IBM 메인 프레임 사이트에서 작업하는 경우 사용해야하는 JOB 카드의 형식을 알고 있습니다. 최소한의 JOB 카드는 내가 보여준 것처럼 주석없이입니다. 예를 들어, 회계 정보를 제공해야하므로 주석이 중요합니다. 작업 이름은 사이트 별 형식 일 수 있습니다.

일부 사이트는 INTRDR의 사용을 금지하거나 금지합니다. 알아 두세요

일부 사이트에서는 이름이 같은 여러 작업을 동시에 실행할 수 있습니다. 알아 두세요

시스템 프로그래머가 아닌 한 그러한 클래스를 설정할 수는 없지만 하나의 초기자를 허용하는 클래스를 찾아야합니다. 이를 통해 프로세스는 상당히 안전하지만 클래스가 설명대로 작동하는지 절대적으로 확인하십시오. 테스트. 이 직업에는 없습니다.

귀하가 시스템 프로그래머 인 경우, 귀하는 송금 이외의 행동을하지 않아야합니다. '그런가 말했다.

같은 이름을 가진 하나의 작업이 동시에 허용되고 단일 이니시에이터를 사용하면 작업 시작 / 종료 다음 작업 시작 / 종료의 연속 스트림이됩니다. 수천 개의 작업 (또는 작업 번호가 부족) JES 콘솔에서 경고 메시지를 확인하십시오.

기본적으로이 작업을 수행하지 마십시오. 그렇게하는 경우 프로덕션 시스템에서 수행하지 마십시오.

약간의 솔질로, 다른 IBM 메인 프레임 운영 체제 인 z / VSE ... z / VSE에서 ​​JCL을 사용하는 방법에 대한 또 다른 답변을 고려할 것입니다. z / OS는 JCL을 사용합니다. 그들은 달라요 :-)


아이디어는 좋아 보이지만 답은 아닙니다. JCL (JOB, EXEC 및 DD)을 알려 주면 답이 될 것입니다.
ugoren

오래 동안 일자리를 제출하지 않았기 때문에 무엇을해야할지 모르겠습니다. 누락 된 부품이 로컬 사용자 정의 인 경우 확인을 클릭하십시오. 그러나 남용을 방지하기 위해 물건을 숨기면 마음을 정하십시오. 실제 내용을 게시하거나 아무 것도 게시하지 마십시오. 추신 : 우리는 IEBGENER그때 단순히 복사하기 위해 사용했습니다 .
ugoren

@ugoren IEBGENER가 작업에 대해 선택되지 않은 이유에 대한 설명을 포함한 추가 업데이트. JOB 문에서 주석 텍스트를 제거하면 JCL을 실행하는 데 필요한 JCL이 제공되지만 JCL이 충분하면 작업이 작동하거나 프로그래머가 해킹 당하지 않도록 로컬 사이트 표준에 따라 다릅니다.
Bill Woodger

4

파이썬 (72 바이트)

import os
os.system('kill -9 %s && python %s' % (os.getpid(), __file__))

더 작게 만들 수있을 것 같아요. 먼저을 사용하는 대신 파일 이름을 하드 코딩합니다 __file__. 그러나 여기서는이 코드를 파일에 넣고 이름에 관계없이 실행할 수 있습니다. :)


당신은 아마 변경할 수 있습니다 &&&.
Hosch250

1
언제 허용됩니까, user2509848?
Rhymoid

글쎄, 당신은 공백을 제거하여 시작할 수 있습니다 ...
Ry-

6
code-golf 태그가 지정되지 않았으므로 다음 과 같이 코드를 유지합니다.
Maxime Lorant

4

Windows 작업 스케줄러 (.BAT)

Windows 배치 스크립트. 모든 도전 요구 사항을 충족합니다.

내가 볼 수있는 한 이것은 모든 요구 사항을 충족하고 비표준 종속성이없는 유일한 Windows 솔루션입니다 (다른 솔루션은 비슷하지만 컴파일이 필요합니다).

@ECHO OFF
SETLOCAL

schtasks /Delete /TN RestarterCL /F

ECHO Close this window now to stop.
TIMEOUT /T 5

FOR /f "tokens=1-2 delims=: " %%a IN ("%TIME%") DO SET /A now=%%a*60+%%b
SET /A start=%now%+1
SET /A starth=100+(%start%/60)%%24
SET /A startm=100+%start%%%60
SET /A end=%now%+3
SET /A endh=100+(%end%/60)%%24
SET /A endm=100+%end%%%60

schtasks /Create /SC ONCE /TN RestarterCL /RI 1 /ST %starth:~1,2%:%startm:~1,2% /ET %endh:~1,2%:%endm:~1,2% /IT /Z /F /TR "%~dpnx0"

ENDLOCAL

프로그램은 C ++ / COM answer 와 유사하게 작동 합니다.

프로그램은 Windows 작업 스케줄러를 사용하여 일회성 작업을 시작하고 등록하여 최대 60 초 후에 시작합니다 (제어판-> 관리 도구-> 작업 스케줄러, 확인하려면 작업 이름이 "다시 시작"). 프로그램은 작업을 생성하기 전에 프로그램을 종료 할 수있는 5 초 동안 일시 중지됩니다.

명령 줄 작업 스케줄러 인터페이스를 사용 schtasks.exe합니다. 스크립트의 산술은 시간을 유효하게 유지하면서 HH : MM 형식으로 시간 오프셋을 계산하는 것입니다.

도전 과제 :

  • 완료되면 다시 시작됩니다. 예. 작업은 프로그램 종료 직전에 예약됩니다.

  • 동시에 실행되는 프로그램의 인스턴스는 두 개 이상입니다. 예. 프로그램이 완전히 종료되고 ~ 60 초 동안 실행되지 않습니다. 스케줄러에 의해 시작됩니다.

  • 주기 동안 사용자가 수동으로 시작한 인스턴스는 무시해도됩니다. 예, 일정한 작업 이름을 사용하는 부작용으로 그렇습니다.

  • 다시 시작하는 것이 보장되는 한. 예, 작업 스케줄러가 실행 중이고 schtasks.exe가있는 경우 (기본 Windows 구성 모두에 해당).

  • 주기를 중지하는 유일한 방법은 프로세스를 종료하는 것입니다. 예, 5 초 동안 프로세스가 종료되는 동안 프로세스가 종료 될 수 있습니다. 프로그램은 5 초 지연 이전에 작업을 삭제하며이 시점에서 작업을 종료하면 스케줄러에 흩어진 작업이 남지 않습니다.

  • 솔루션을 다시 시작하면 안됩니다 . 예.

참고 : 명령 줄 인터페이스가 제한되어 있으므로 재시작 시간을 분 단위로 지정해야하며 AC 어댑터를 연결하지 않은 랩탑에서 작업을 다시 시작하지 않아야 합니다 (죄송합니다).


3

유닉스 쉘

아직 관련없는 프로그램을 사용하여 다시 시작하는 솔루션이 많이 보이지 않았습니다. 그러나 이것은 at(1)유틸리티가 만들어진 것입니다.

echo "/bin/sh $0"|at now + 1 minute

분당 한 번만 실행되고 너무 빨리 종료되므로 실제로 프로그램을 실행하는 것은 어렵습니다. 다행히도 atq(1)유틸리티는 여전히 진행 중임을 보여줍니다.

$ atq
493     Fri Feb 21 18:08:00 2014 a breadbox
$ sleep 60
$ atq
494     Fri Feb 21 18:09:00 2014 a breadbox

그리고 atrm(1)당신은 사이클을 깰 수 있습니다 :

$ atq
495     Fri Feb 21 18:10:00 2014 a breadbox
$ atrm 495
$ atq

당신은 대체 할 수 1 minute와 함께 1 hour, 또는 1 week. 또는 1461 days4 년마다 한 번씩 실행되는 프로그램을 갖도록하십시오.


2

PowerShell

나는 내 자신의 규칙을 남용하고있다.

[System.Threading.Thread]::Sleep(-1)

자체 재시작에는 시간이 오래 걸립니다.
호스트 프로세스를 종료하여 종료 할 수 있습니다.

두고 봐 ;)


5
창의력은 +1, 부정 행위는 -1
Johannes H.

1
하, 그러나 그것이 멈추지 않으면 "다시 시작된다는 보장"인가?
Jason C

그래서 내가 규칙을 어길 것이라고 말한 것입니다. 그 후에 어떤 일이 일어날 수 있다고 가정 할 수있는 것은 철학의 무한한 아름다움입니다. 튜링 머신도 그렇게 작동합니다.
microbian

1
-100, 특히 기술면에서 자신의 컨테스트 우승을 지원하지 않기 때문에 -100이지만 다시 시작하기를 기다리는 것이 최고의 지연 변명이므로 +101입니다.
Jason C

글쎄요, 그다음에 while true; do sleep 1; done퀼 리즈하지 않습니까?
yo '

2

세게 때리다

echo -e "$(crontab -l)\n$(($(date "+%M")+1)) $(date '+%H %e %m * /repeat.sh')" | crontab -

이것을 / 디렉토리에 repeat.sh로 저장하고 실행 권한을 부여하십시오. 파일을 삭제하면 죽일 수 있습니다

이것은 crontab에 항목을 넣어서 1 분 후에 실행함으로써 작동합니다.


2

Visual Base 6 :)

Sub Main:Shell "cmd ping 1.1.1.1 -n 1 -w 500>nul&&"""&App.Path &"\"&App.EXEName& """":End Sub

실행하려면 새 프로젝트를 만들고이 코드를 사용하여 모듈을 추가하고 시작 개체를 "Sub Main"으로 설정하고 컴파일 한 다음 실행 파일을 실행하십시오.


더 읽기 쉬운 버전 :

Sub Main()
    Call Shell("cmd ping 1.1.1.1 -n 1 -w 3000 > nul && """ & App.Path & "\" & App.EXEName & """")
End Sub

VB6은 실제 사람의 VB입니다. 그 종류의 마지막!
Jason C


1

세게 때리다

그것보다 더 길지만 피곤하고 신경 쓰지 않습니다. :)

while true; do sleep 1; done; bash $0;

완료되면 다시 시작해야한다고 반복적으로 또는 무기한으로 다시 시작해야한다고 구체적으로 말하지 않았습니다. 또한 한 번에 두 개의 인스턴스를 실행해서는 안된다고 말했지만 결코 그렇지 않습니다. ;)

이를 수행하는 방법에는 여러 가지가 있습니다. 내가 개인적으로 좋아하는 것은 먼 곳에서 패킷을 보낸 다음 (어떻게 든 여러 방법을 통해) 응답을 보내 프로세스를 트리거하는 것과 같은 일을하는 것입니다.


기술적으로 sleep프로세스가 완료되면 다시 시작됩니다
ace_HongKongIndependence

프로그램이 self 를 다시 시작하는 프로그램 인 경우 무한정으로 다시 시작해야 함을 의미합니다. 그렇지 않으면 자체가 아닌 다른 것을 다시 시작하는 것입니다.
Jason C

@Jason C : 너무 철학적이지 않고, 가능한 한도 내에서 다시 시작됩니다. 우리는 그것을 스스로 다시 시작하는 것이 얼마나 복잡해야하는지에 대해 토론 할 수는 있지만 저자의 의미를 넘어서는 것이라고 생각합니다. 그러나 실제로 다시 시작하기를 원한다면 goto 또는 JMP를 사용하거나 언어가 제공하는 구성을 사용하여 시작으로 돌아가는 것일 수 있으므로 "다시 시작"됩니다. 그렇지 않으면, 그것은 분명히 자신과 비슷한 것을 실행하고 있습니다. 그러나 누군가가 실제로 다시 시작되지 않는 문제를 일으킬 것입니다. 그래서 나는 탈선했다.
Ian Wizard

1

Android : 1 초 후에 알람이 활동을 다시 시작합니다

public class AutoRestart extends Activity
{

@Override
public void onCreate()
{
    finish();
}

@Override
public void onDestroy() {

    Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
    restartServiceIntent.setPackage(getPackageName());

    PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmService.set(
            AlarmManager.ELAPSED_REALTIME,
            SystemClock.elapsedRealtime() + 1000,
            restartServicePendingIntent);

    super.onDestroy();
}

}

1

C + MPI 환경

mpifork.c :

#include <stdio.h>

main(int argc, char * argv[])
{
    srand(time(NULL));
    int host = rand()%(argc-1)+1;
    FILE * logFile = fopen("mpifork.log", "a");
    if(logFile == NULL){
        fprintf(stderr, "Error: failed to open log file\n");
    } else {
        fprintf(logfile, "Jumping to %s\n", argv[host]);

        char * args[argc+5];
        args[0] = "mpirun";
        args[1] = "-H";
        args[2] = argv[host];
        args[3] = argv[0];
        for(host = 0; host < argc-1; host++) args[host+4] = argv[host+1];
        args[argc+3] = NULL;

        execvp("mpirun", args);
        fprintf(stderr, "exec died\n");
        perror("execvp");
    }
}

OpenMPI 또는 다른 MPI 구현이 설치되어 있어야합니다. 와 컴파일

mpicc -o mpifork mpifork.c

이제 그것에 대해 생각 했으므로 mpicc-gcc 또는 컴파일러가 작동하는 것을 사용해야 할 이유가 없습니다. mpirun 만 있으면됩니다.

gcc -o mpifork mpifork.c

이를 실행하려면 전체 경로 이름을 포함하고 호스트 목록을 포함해야합니다. 예를 들어, / etc / hosts에 모두 localhost를 가리키는 항목을 추가하고 다음과 같이 실행했습니다.

/home/phil/mpifork localhost localhost1 localhost2 localhost3 localhost4

실행 파일은이 파일을 실행할 시스템의 동일한 디렉토리에 있어야합니다.


기본적으로 명령 행에 제공된 호스트 목록을 가져 와서 호스트 중 하나를 선택한 후 동일한 인수를 사용하여 대상 호스트에서 실행 파일을 시작합니다. 모든 것이 완벽하게 진행되면 mpirun은 다른 머신 (또는 'localhost'만 제공하는 경우 동일한 머신)에서 계속해서 자신을 호출 execvp합니다.

악의를 갖고 싶다면 대신 에 명령 행에 제공된 전체 호스트 목록을 포함시켜 모든 머신에서 이를 실행할 수 args있습니다. 그것은 모든 컴퓨터에서, 그 자체로 복제본을 생성합니다.

그러나이 형식에서는 이것이 규칙을 충족한다고 확신합니다.


1

자바 스크립트

필요하지 않을 때 "네트워크로 이동"하지 않으면 :-) JavaScript의 이벤트 루프 스케줄링을 통해 주어진 요구 사항을 매우 쉽게 충족시키는 프로그램을 작성할 수 있습니다.

(function program() {
    // do what needs to be done
    setTimeout(program, 100);
})();

program기능은 초당 10 회 속도로 기능을 "재조정"합니다 . JavaScript의 특성상 단일 작업 만 동시에 실행되며 "페이지 다시로드"와 같이 "환경을 다시 시작하지"않습니다.


0

x86 조립

이것이 새로운 프로세스를 생성하지 않기 때문에 이것이 귀하의 기준에 맞는지는 확실하지 않지만, 여기에 있습니다.

프로그램은 메시지 상자를 표시하고, 일부 메모리를 할당하고, 자체 코드 섹션을 할당 된 메모리에 복사 한 다음 순환을 시작하는 해당 위치로 이동합니다. malloc이 실패 할 때까지 실행해야합니다.

format PE GUI 4.0
entry a

include 'include/win32a.inc'

section '.text' code readable executable

    a:
        push    0
        push    _caption
        push    _message
        push    0
        call    [MessageBoxA]

        push    b-a
        call    [malloc]

        push    b-a
        push    a
        push    eax
        call    [memcpy]

        call    eax
    b:

section '.data' data readable writeable

    _caption db 'Code challenge',0
    _message db 'Hello World!',0

section '.idata' import data readable writeable

    library user,'USER32.DLL',\
        msvcrt,'msvcrt.dll'

    import user,\
        MessageBoxA,'MessageBoxA'

    import msvcrt,\
        malloc,'malloc',\
        memcpy,'memcpy'

fasm으로 컴파일되었습니다.


4
새로 복사 된 코드를 호출하는 것이 프로그램의 일부이므로 기술적으로 프로그램은 전혀 끝나지 않았습니다.
microbian

6
낮은 수준의 관점에서, 여기의 모든 프로그램에 대해서도 마찬가지입니다. :-)
Brian Knoblauch

@BrianKnoblauch 동의하지 않습니다. 여기서 가장 흥미로운 답변은 시스템 환경을 수정하여 첫 번째 프로세스가 종료 된 후 언젠가 프로세스의 새 사본이 시작되도록하는 것 같습니다. 예를 들어, 미래에 프로세스를 실행하기 위해 동기 작업을 작성하면 프로세스를 완전히 종료 한 다음 다시 시작할 수있는 좋은 방법이라고 생각합니다.
복원 모니카

2
@BrianKnoblauch 사실은 아닙니다. 프로세스는 운영 체제 구성입니다 (요즘-1982 년 286의 보호 모드가 출현 한 이래로 가상 주소 공간과 보호 메모리를 통한 하드웨어에 의해 지원됨). 그것이 끝나면 모든 정보가 사라집니다. 챌린지에 명시 적으로 명시되어 있지는 않지만, "재시작"은 새로운 프로세스 ID가 할당되었음을 의미하는 챌린지의 정신을 취합니다.
Jason C

글쎄, 당신이 도중에 메모리를 확보 할 수 있다면 +1을 줄 @것입니다 (내가 눈을 떼지 않을 것이므로 관리하면 한 번 ping 하십시오).
yo '

0

리눅스 시작 스타트

질문을 가장 엄격하게 읽으면 이것이 불가능하다고 생각합니다. 본질적으로 프로그램을 실행중인 다른 프로그램의 도움으로 자발적으로 시작하도록 요구하고 있습니다.

이 몇 가지 atchron기반 대답은하지만 엄격한 읽기에, atd그리고 anacron그들이 자격을 박탈 할 수 있도록, 모든 시간을 실행하는 보조 프로그램입니다.

관련 접근법이지만 약간 낮은 수준은 Linux를 사용하는 것 init입니다. 루트로이 .conf 파일을 /etc/init/다음에 추가하십시오 .

설명 "영원히"

런레벨에서 시작 [2345]
런레벨에서 멈춤 [! 2345]

리스폰

임원 수면 10

그런 다음 init.conf 파일 을 다시 읽습니다.

sudo telinit 5

sleep10 초 동안 진행되는 프로세스 가 시작되고 종료됩니다. init그런 다음 sleep이전 항목이 사라지면 다시 생성 됩니다.

물론 이것은 여전히 init보충 프로그램으로 사용되고 있습니다. init이것이 커널의 논리적 확장이며 모든 Linux에서 항상 사용할 수 있다고 주장 할 수 있습니다.

이것이 받아 들일 수 없다면, 다음으로해야 할 일은 사용자 공간 프로세스를 다시 생성하는 커널 모듈을 만드는 것입니다 (얼마나 쉬운지는 확실하지 않습니다). 여기서 커널은 프로세스가 아니므로 프로그램 (보조)이 아니라고 주장 할 수 있습니다. 반면에 커널은 CPU 관점에서 볼 때 자체적으로 프로그램입니다.


-1

TI-BASIC : 5 자

불러라 prgmA

:prgmA

나는 6 문자를 셀 수 있습니다. TI-BASIC 프로그램 크기 계산에 특별한 것이 있습니까?
ace_HongKongIndependence

:당신이 TI-기본으로 프로그래밍 할 때마다 라인 심볼의 시작에 불과하다. 입력 한 것이 아니라 편집기에 있습니다.
scrblnrd3

정보를 주셔서 감사합니다
ace_HongKongIndependence

재귀 호출이 아닌가? A값을 증분 하여 기본 사례로 사용하면 결국 밖으로 나가는 것을 볼 수 있습니다.
ζ-- 2019

모든 변수는 ti-basic의 전역 변수이므로 확실하지 않습니다. 그것은 수 있습니다
scrblnrd3
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.