Program yang berakhir tetapi tidak pernah berakhir [ditutup]

35

Tulis program yang memulai sendiri lagi ketika selesai.

Seharusnya tidak ada lebih dari satu contoh program yang berjalan pada saat yang sama. Bahkan untuk momen sekecil apa pun.

Anda dapat mengabaikan setiap instance yang dimulai secara manual oleh pengguna selama siklus Anda. Tetapi kode Anda seharusnya tidak melakukannya dalam siklus restart Anda.

Program dapat dimulai setelah jumlah waktu berapa pun, asalkan dijamin akan mulai lagi.

Satu-satunya cara untuk menghentikan siklus adalah dengan mematikan prosesnya.

Solusi Anda seharusnya tidak melibatkan restart lingkungan (di mana program sedang berjalan, termasuk OS, mesin, VM, shell dll). Hanya program Anda yang diizinkan memulai ulang.

mikrobia
sumber
11
Bukankah ini yang execada di linux?
mniip
11
Saya agak malas untuk menulisnya sekarang, tetapi kiriman saya akan (untuk windows): "Edit registri sehingga program saya boot pada saat startup. Jalankan shutdown -r -t 0 -f".
Cruncher
3
Membunuh proses tidak akan membunuh siklus Anda.
microbian
19
Saya baru sadar: jika saya ingin menulis virus dan tidak tahu caranya, saya bisa 1) pergi ke StackOverflow, tanyakan caranya. Dapatkan kebencian dari semua orang dan mungkin pertanyaannya akan ditutup. Atau 2) Pergi ke golf kode, tanyakan orang lain bagaimana mereka melakukannya. Dapatkan beberapa jawaban kreatif untuk dipilih, dan pertanyaannya sangat populer sehingga masuk dalam daftar "panas" di seluruh jaringan. Mua ha ha ha ha.
rumtscho
5
@rumtscho Anda tahu, itu strategi umum yang bagus. Ok teman-teman, untuk tantangan saya berikutnya, mari kita lihat siapa yang dapat menulis firmware terkecil untuk perangkat prototipe yang ada di meja saya yang memenuhi semua persyaratan dalam dokumen tertaut. Untuk meningkatkannya, ini harus dilakukan jam 8 pagi Senin pagi. Pergi!
Jason C

Jawaban:

50

Skrip Bash, 3 karakter (Terpendek, mungkin paling elegan, meskipun diakui kontroversial)

$0&

Cukup tempatkan instance baru dari dirinya sendiri di latar belakang (proses baru), lalu berhenti. Instance baru kemungkinan akan tetap berada di antrian run-scheduler hingga instance sebelumnya selesai.

Peringatan - ini sulit dilakukan kill, karena PID terus berubah. Mengganti nama sementara file skrip mungkin merupakan cara paling sederhana untuk memutus siklus.

Sistem single-core diasumsikan. Tentu saja ini tidak realistis dengan Linux pada perangkat keras bare-metal modern, tetapi mudah dikonfigurasi saat dijalankan dalam VM. Kami mungkin dapat mencapai trik serupa menggunakan taskset, tetapi itu akan mengurangi dampak dari solusi 3-char.

Jawaban ini sedikit membengkokkan aturan karena menerapkan arti khusus "berlari". Akan ada saat-saat ketika proses baru telah fork()ed dan proses lama masih hidup - yaitu mungkin untuk mengamati lebih dari satu PID. Namun proses baru akan ditempatkan pada run-queue scheduler Linux untuk menunggu siklus CPU, sementara proses yang ada akan terus dijalankan. Pada titik ini semua yang perlu dilakukan oleh proses yang ada adalah untuk bashdirinya sendiri exit(). Ini memang membutuhkan waktu yang terbatas, meskipun saya cukup yakin bahwa itu akan dilakukan jauh sebelum kuantum kutu waktu / scheduler saat ini dilakukan. Bukti pendukung adalah fakta yang bashdimulai dan dimatikan dalam 2ms di VM saya:

$ time bash -c:

0m0.002s nyata
pengguna 0m0,000s
sys 0m0,000s
$ 

Bukti pendukung lebih lanjut bahwa proses baru tidak benar-benar berjalan sampai proses sebelumnya dilakukan dapat dilihat pada straceoutput:

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

Dalam output, kita melihat proses asli memiliki PID 6929. Kita bisa melihat fork()panggilan (sebenarnya clone()), yang mengembalikan PID baru dari 6930. Pada titik ini ada 2 PID, tetapi saat ini hanya 6929 yang sedang berjalan:

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 baca (255, "", 4) = 0
6929 12: 11: 01.031907 exit_group (0) =?
6930 12: 11: 01.032016 close (255) = 0
6930 12: 11: 01.032052 rt_sigprocmask (SIG_SETMASK, [], NULL, 8) = 0

straceOutput penuh di sini.

Kita dapat melihat bahwa 6930 tidak mengeluarkan panggilan sistem apa pun hingga 6929 selesai sepenuhnya. Masuk akal untuk mengasumsikan bahwa ini berarti 6930 tidak berjalan sama sekali sampai 6929 selesai. The perfutilitas akan menjadi cara utama untuk membuktikan ini.

Trauma Digital
sumber
21
"restart ..., lalu berhenti", jadi lebih dari satu contoh berjalan pada saat yang sama?
microbian
4
"... pada single core" - ya, saya kira begitu juga. Pada banyak inti, Anda mungkin dapat melihat banyak.
blabla999
3
Jika ini ditandai dengan kode-golf, maka ini pasti akan menang! +1
John Odom
3
@DigitalTrauma Anda membuat asumsi besar tentang berapa lama waktu yang dibutuhkan untuk menutup diri. top tidak memberi tahu Anda apa-apa - hanya pembaruan sekali setiap beberapa (puluhan) detik tetapi Anda menghasilkan banyak proses per detik.
David Richerby
2
@ DavidRicherby - Anda benar sekali - topbukan alat yang tepat untuk digunakan di sini. Namun saya melihat bahwa time bash -c :hanya membutuhkan 2ms pada Ubuntu VM saya, jadi saya tidak berpikir itu tidak masuk akal bashuntuk menyelesaikan shutdownnya sebelum penjadwalan kuantum dilakukan.
Digital Trauma
26

Solusi 1

PHP, 32 karakter

Ia mengirim header dan kemudian berhenti. Setelah 3 detik, halaman dimuat ulang.

mengajukan a.php

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

Ini dapat dihentikan dengan menghentikan eksekusi halaman sebelum header dikirim, atau hanya dengan membunuh browser.


Solusi 2

PHP, 2 halaman

Mari kita perhatikan dua file dua program berbeda. Dua file berada di folder yang sama.

mengajukan a.php

header("Location:b.php");

file b.php

header("Location:a.php");

Mengakhiri salah satu halaman sebelum tajuk dikirim mengakhiri program (membunuh browser juga berfungsi).

Berikut program yang sama di

ASP.NET

file a.aspx

Response.Redirect("b.aspx")

file b.aspx

Response.Redirect("a.aspx")
Vereos
sumber
1
Itu solusi yang bagus. Saya berharap orang lain datang dengan jawaban yang berbeda dari ini. Itu sebabnya saya menyimpannya sebagai kontes popularitas.
microbian
Apakah jawaban reload 3 detik Anda valid atau tidak, saya serahkan ke ahli php. Saya pikir ini mungkin valid, karena browser yang menunggu bukan php Anda (saya bukan ahli).
microbian
1
Meskipun secara teknis PHP dijalankan sebagai modul dari server web dan server web Anda tidak restart, saya pikir itu valid jika Anda menganggap file .php sebagai skrip dan skrip dijalankan beberapa kali.
TwiNight
@TwiNight Terima kasih atas umpan baliknya, saya menghargainya :)
Vereos
2
Untuk solusi kedua Anda, bukankah browser akan mendeteksi loop pengalihan dan berhenti dengan sendirinya? thedan1984.com/wp-content/uploads/2012/02/…
Ajedi32
19

SH

echo $PWD/$0 | at tomorrow

Ini akan bekerja pada semua sistem yang sesuai dengan Posix.

Untuk membunuhnya, hapus file atau gunakan atrm.

ecatmur
sumber
17

pesta

exec "$0"

execmengganti shell tanpa membuat proses baru. Ini memastikan bahwa tidak mungkin ada instance kedua.

Dennis
sumber
1
Lebih baik masukkan saja ~/.bash_profile!
yegle
@Yegle: $0adalah -bashketika .bash_profilebersumber, sehingga hanya akan menghasilkan kesalahan sintaks.
Dennis
Ups, Anda benar.
yegle
exec ${0##-}dalam ~/.bash_profilekarya :-)
yegle
14

Penjadwal Tugas Windows (Asli)

C ++. Mimpi buruk pemrograman COM. Memenuhi semua persyaratan tantangan.

#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);

}

Kompilasi dengan MSVC (atau MinGW GCC jika Anda memiliki semua dependensi).

Program akan memulai dan mendaftarkan tugas satu kali dengan penjadwal tugas Windows untuk memulai sendiri 5 detik kemudian (Control Panel -> Administrative Tools -> Task Scheduler untuk melihat, tugas diberi nama "Restarter"). Program akan berhenti selama 5 detik untuk memberi Anda kesempatan untuk membunuhnya sebelum membuat tugas.

Persyaratan Tantangan:

  • Mulai lagi sendiri saat selesai. Iya nih. Tugas dijadwalkan sebelum keluar dari program.

  • Tidak lebih dari satu contoh program yang berjalan pada saat yang sama. Iya nih. Program keluar sepenuhnya dan tidak berjalan selama 5 detik. Dimulai oleh penjadwal.

  • Anda dapat mengabaikan setiap instance yang dimulai secara manual oleh pengguna selama siklus Anda. Ya, sebagai efek samping dari menggunakan nama tugas yang konstan.

  • Selama dijamin mulai lagi. Ya, asalkan Penjadwal Tugas berjalan (ini dalam konfigurasi Windows standar).

  • Satu-satunya cara untuk menghentikan siklus adalah dengan mematikan prosesnya. Ya, prosesnya bisa dimatikan selama jendela 5 detik saat sedang berjalan. Program menghapus tugas sebelum penundaan 5 detik, membunuhnya pada saat ini tidak akan meninggalkan tugas yang menyimpang dalam penjadwal.

  • Solusi Anda seharusnya tidak melibatkan memulai kembali dari lingkungan Ya.

By the way, jika ada yang bertanya-tanya mengapa aplikasi Windows dulu sangat tidak stabil (sebelum munculnya. NET dan C #), ini adalah salah satu alasan mengapa. Jumlah penanganan kesalahan yang diperlukan (seandainya saya memasukkannya), manajemen sumber daya, dan verbositas mengatur situasi yang sangat rawan kesalahan jika seorang programmer bahkan sedikit malas (kode di atas sangat malas).

Alternatif yang jauh lebih mudah dan lebih pendek adalah dengan memanggil schtasks.exe. Saya telah mengirimkan versi dengan itu dalam skrip .BAT juga.

Jason C
sumber
13

BBC BASIC - penghargaan untuk Snow Patrol

Emulator di bbcbasic.co.uk

Yang ini sedikit berbeda. Ini mencetak satu bait dari lagu "Run" dan memainkan arpeggio dari akord sehingga Anda dapat bernyanyi bersama. Itu terinspirasi oleh fakta bahwa perintah untuk mengeksekusi (dan karena itu baris terakhir dari program) tentu saja berjalan.

Semua variabel dihapus pada awal program, sehingga dibutuhkan warna layar yang ditinggalkan oleh iterasi sebelumnya untuk memutuskan ayat apa yang akan dicetak berikutnya.

    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

OUTPUT (montase dari 4 tangkapan layar yang berbeda)

masukkan deskripsi gambar di sini

Level River St
sumber
+1 untuk solusi warna sebagai alternatif "memori bersama".
Johannes H.
11

HTML / JavaScript:

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

Kode memicu kerusakan halaman yang sedang berjalan, kemudian penciptaan kembali contoh lain dari dirinya sendiri ketika browser memuat halaman baru.

AFAIK, satu-satunya jalan keluar adalah dengan membunuh tab yang digunakan laman.

EDIT: sesuai permintaan populer, kode HTML5 yang valid:

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

sumber
@JasonC, saya tidak setuju. Saya pikir halaman yang masuk akal harus mematuhi spesifikasi, tetapi popularitas-kontes seharusnya cukup masuk akal, bukan? : D jadi +1, saya sangat suka yang ini.
yo
10

C

Program ini bertindak seperti banyak malware. Tepat sebelum ditutup, ia membuat skrip shell di direktori / tmp. Itu garpu untuk memulai skrip shell, yang memungkinkan program asli menutup dan membatalkan PID asli. Setelah periode waktu yang singkat (2 detik) script shell memulai proses baru dengan program. Untuk singkatnya, lokasi program terprogram sebagai '/ 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]);
}

Hanya ada satu proses 'Neverend' yang berjalan pada satu waktu. Setiap proses baru mendapat PID baru. Cara termudah untuk membunuh ini adalah dengan menghapus yang dapat dieksekusi. Jika Anda ingin membuatnya lebih ganas, Anda dapat menyalin skrip yang dapat dieksekusi dan skrip untuk memastikan ada beberapa salinan pada program pada disk kapan saja.

Kevin
sumber
1
Saya mengharapkan jawaban yang lebih inovatif. Lihat komentar untuk pertanyaan tentang 'program suplemen'. Bagi saya, program suplemen hanyalah bagian dari program Anda yang bergaul.
microbian
4
Forking berarti Anda akan memiliki dua contoh proses yang berjalan pada saat yang sama, bahkan jika mereka melakukan hal yang berbeda.
Barry Fruitman
@BarryFruitman mudah dihindari, dengan benar-benar menggunakan dua executable yang berbeda. Itu sah saja, tapi jauh lebih tidak elegan.
Johannes H.
Saya kira Anda bisa menggunakan system()jika aturan tidak menghitung fork + exec /bin/shsebagai program pelengkap.
Jason C
10

Perl

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

Script mengeluarkan perintah sistem untuk mematikan dirinya sendiri, dan menyalurkan hasilnya ke instance lain dari dirinya sendiri. Penerjemah Perl digunakan untuk melakukan pembunuhan, karena alasan lintas platform.

Hentikan kegilaan dengan menghapus skrip.

primo
sumber
7

Atari 8-bit Basic

1L.:R.

Ditandai untuk:

1 LIST : RUN

Secara internal itu membersihkan struktur internal, pada dasarnya menghapus program, sebelum menjalankannya lagi dari daftar.

Ini pada dasarnya berbeda dari:

1L.:G.1

Yang tokenizes ke:

1 LIST : GOTO 1

Ini adalah loop tak terbatas dasar. Ketika Anda menjalankannya, Anda melihat perbedaan dalam kecepatan (pertama lebih lambat).


sumber
Saya tidak begitu jelas mengapa "daftar" selama pelaksanaan program akan menghapus struktur antar ginjal. Saya pikir Atari memiliki buffer keyboard, sehingga orang dapat membuat daftar program, memasukkan penekanan tombol untuk menjalankannya, dan melakukan "baru" dengan kursor diposisikan untuk "mengetik ulang" itu.
supercat
@supercat - DAFTAR tidak, RUN melakukannya.
Dengan logika itu, seseorang bisa menghilangkan "LIST". Di sisi lain, jika program memasukkan buffer keyboard, dengan beberapa carriage return, letakkan "NEW" diikuti oleh program dan "RUN" di tempat yang tepat di layar, menempatkan kursor, dan keluar, itu akan benar-benar menghapus dirinya sendiri dan ketik ulang itu sendiri secara otomatis.
supercat
@supercat - tanpa LIST, Anda tidak akan melihatnya berjalan. Saya memilih LISTkarena memiliki input terpendek L.. Saya suka ide memasukkannya ke dalam buffer keyboard, itu tentu saja cukup singkat!
Apakah saya ingat benar bahwa Atari, seperti mesin Commodore, membaca teks dari layar ketika Anda menekan Return? Seberapa besar buffer keyboard? Pada VIC-20 dan C64, ini sepuluh byte. Sebuah program yang melakukan cukup colekan untuk memuat buffer keyboard mungkin tidak cocok dengan buffer keyboard, tetapi saya telah menulis program yang akan memodifikasi diri mereka sendiri dengan mencetak perubahan pada layar diikuti RUN, dan melakukan beberapa Returnpenekanan tombol. Hal-hal seperti itu sangat berguna pada 64 karena tidak memiliki perintah [IIRC] INyang Atari miliki untuk menggabungkan baris ke dalam sebuah program.
supercat
5

Pada IBM Mainframe yang menjalankan z / OS, Anda menjalankan utilitas yang menyalin dataset (file) ke dataset lain (file). Input adalah sumber dari JCL (Job Control Language) yang telah Anda kirimkan untuk menjalankannya. Outputnya adalah Internal Reader (INTRDR). Anda juga perlu memastikan bahwa sistem Anda tidak mengizinkan jalannya beberapa nama pekerjaan yang identik. Baik untuk menggunakan kelas pekerjaan yang hanya memiliki satu inisiator (tempat di mana JOB dapat berjalan dalam batch).

Tidak ada PID yang terlibat (dalam z / OS), jadi gagal dengan tantangan yang ditetapkan.

Anda menghentikan proses dengan pengeringan dan / atau pembilasan. Jika ada yang tidak beres, dengan mengeringkan dan / atau menyiram, mengumpat, menendang, mencoba memulai dengan hangat dan akhirnya dengan memulai dengan dingin atau mengenai Tombol Merah Besar (dan menembak programmer).

Saya mungkin telah melebih-lebihkan di sepanjang jalan, tetapi jangan mencoba ini di tempat kerja ...

Contoh menggunakan SORT. Rincian pada kartu JOB sangat tergantung pada situs. Kebijakan situs dapat melarang atau mencegah penggunaan INTRDR. Kelas tertentu mungkin diperlukan untuk menggunakan INTRDR. Jika kebijakan situs Anda melarang penggunaannya, jangan gunakan kecuali Anda ingin mengambil barang-barang Anda untuk berjalan-jalan di kotak kardus.

Meskipun ada kegunaan yang baik untuk INTRDR, jangan menggunakannya untuk tujuan ini . Anda bahkan tidak akan memiliki kesempatan untuk mendapatkan kotak Anda.

//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) 

Utilitas lain tersedia. Program cepat akan mudah dilakukan juga, cukup baca file, tulis file.

Jika Anda ingin contoh kesalahan ini, coba: http://ibmmainframes.com/viewtopic.php?p=282414#282414

Cara tradisional untuk menyalin dataset adalah dengan menggunakan utilitas IBM IEBGENER, sebagaimana ugoren menyinggung dalam komentar mereka.

Namun, hari-hari ini, banyak situs akan memiliki IEBGENER "alias" untuk ICEGENER. ICEGENER akan, jika dapat, menggunakan DFSORT IBM (atau SyncSort saingannya) untuk melakukan salinan, karena produk-produk SORT jauh lebih dioptimalkan untuk IO daripada IEBGENER.

Saya hanya memotong perantara dengan menggunakan SORT.

Jika Anda bekerja di situs IBM Mainframe, Anda tahu format kartu JOB yang harus Anda gunakan. Kartu JOB minimal seperti yang saya tunjukkan, tanpa komentar. Komentar akan menjadi penting, karena Anda mungkin seharusnya memberikan informasi akuntansi, misalnya. Nama pekerjaan kemungkinan akan memiliki format khusus situs.

Beberapa situs melarang, atau mencegah, penggunaan INTRDR. Waspadalah.

Beberapa situs memungkinkan beberapa pekerjaan dengan nama yang sama dijalankan pada saat yang bersamaan. Waspadalah.

Meskipun kecuali Anda adalah Programmer Sistem Anda tidak dapat mengatur kelas seperti itu, Anda harus mencari kelas yang hanya memungkinkan satu inisiator. Dengan itu, prosesnya cukup aman - tetapi pastikan benar-benar bahwa kelas berfungsi sebagaimana dijelaskan. Uji. Tidak dengan pekerjaan ini.

Jika Anda seorang Programer Sistem, Anda tahu untuk tidak melakukan apa pun di luar remit Anda. kata Nuff.

Dengan satu pekerjaan dengan nama yang sama diizinkan pada saat yang sama dan satu inisiator, ini akan menjadi aliran awal pekerjaan / selesai pekerjaan berikutnya mulai / selesai - sampai Anda mengisi gulungan (hal buruk yang harus dilakukan) dengan output dari ribuan pekerjaan (atau kehabisan nomor pekerjaan). Tonton Konsol JES untuk pesan peringatan.

Pada dasarnya, jangan lakukan ini. Jika Anda melakukannya, jangan lakukan itu di mesin Produksi.

Dengan sedikit mempercepat, saya akan mempertimbangkan Jawaban lain untuk bagaimana melakukannya pada sistem operasi IBM Mainframe lain, z / VSE ... z / VSE menggunakan JCL. z / OS menggunakan JCL. Mereka berbeda :-)

Bill Woodger
sumber
Idenya terlihat bagus, tetapi itu bukan jawaban. Tunjukkan kami JCL - JOB, EXEC dan DD - maka itu akan menjadi jawaban.
ugoren
Belum pernah mengirimkan pekerjaan terlalu lama, jadi saya tidak yakin apa yang harus dilakukan. Jika bagian yang hilang hanya kustomisasi lokal, maka OK. Tetapi jika Anda menyembunyikan hal-hal untuk mencegah penyalahgunaan, maka putuskan pikiran Anda - posting hal yang sebenarnya, atau posting apa-apa. PS Kami dulu IEBGENERhanya menyalin.
ugoren
@ugoren Pembaruan lebih lanjut, termasuk penjelasan mengapa IEBGENER tidak dipilih untuk tugas tersebut. Menghapus teks komentar pada pernyataan JOB memberikan JCL yang diperlukan untuk menjalankannya, tetapi menjadi cukup JCL tergantung pada standar situs lokal, baik untuk pekerjaan untuk bekerja atau untuk programmer untuk menghindari pemecatan.
Bill Woodger
4

Python (72 byte)

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

Bisa jadi lebih kecil kurasa. Pertama, dengan meng-hardcoding nama file (alih-alih menggunakan __file__). Tapi di sini, Anda bisa meletakkan kode ini dalam file dan menjalankannya, apa pun namanya :)

Maxime Lorant
sumber
Anda mungkin bisa berubah &&menjadi &.
Hosch250
1
Sejak kapan itu diizinkan, user2509848?
Rhymoid
Nah, Anda bisa mulai dengan menghapus spasi ...
Ry-
6
Karena tidak ditandai kode-golf , saya akan menyimpan kode seperti ini :-)
Maxime Lorant
4

Penjadwal Tugas Windows (.BAT)

Skrip kumpulan Windows. Memenuhi semua persyaratan tantangan.

Sejauh yang saya bisa lihat, ini adalah satu-satunya solusi Windows yang memenuhi semua persyaratan dan tidak memiliki dependensi yang tidak standar (solusi saya yang lain serupa tetapi membutuhkan kompilasi).

@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

Program berperilaku serupa dengan jawaban C ++ / COM saya .

Program akan memulai dan mendaftarkan tugas satu kali dengan penjadwal tugas Windows untuk memulai sendiri hingga 60 detik kemudian (Control Panel -> Administrative Tools -> Penjadwal Tugas untuk melihat, tugas diberi nama "Restarter"). Program akan berhenti selama 5 detik untuk memberi Anda kesempatan untuk membunuhnya sebelum membuat tugas.

Menggunakan antarmuka baris perintah Penjadwal Tugas schtasks.exe. Aritmatika dalam skrip adalah untuk menghitung offset waktu sambil menjaga waktu tetap valid dan dalam format HH: MM.

Persyaratan Tantangan:

  • Mulai lagi sendiri saat selesai. Iya nih. Tugas dijadwalkan sebelum keluar dari program.

  • Tidak lebih dari satu contoh program yang berjalan pada saat yang sama. Iya nih. Program keluar sepenuhnya dan tidak berjalan selama ~ 60 detik. Dimulai oleh penjadwal.

  • Anda dapat mengabaikan setiap instance yang dimulai secara manual oleh pengguna selama siklus Anda. Ya, sebagai efek samping dari menggunakan nama tugas yang konstan.

  • Selama dijamin mulai lagi. Ya, asalkan Penjadwal Tugas berjalan dan schtasks.exe hadir (keduanya benar dalam konfigurasi Windows standar).

  • Satu-satunya cara untuk menghentikan siklus adalah dengan mematikan prosesnya. Ya, prosesnya bisa dimatikan selama jendela 5 detik saat sedang berjalan. Program menghapus tugas sebelum penundaan 5 detik, membunuhnya pada saat ini tidak akan meninggalkan tugas yang menyimpang dalam penjadwal.

  • Solusi Anda seharusnya tidak melibatkan memulai kembali dari lingkungan Ya.

Catatan: Karena antarmuka baris perintah terbatas, waktu mulai ulang harus ditentukan dalam beberapa menit dan tugas tidak akan dimulai ulang pada laptop tanpa adaptor AC terpasang (maaf).

Jason C
sumber
3

Unix shell

Saya belum melihat banyak solusi yang bergantung pada program yang tidak terkait untuk memulai kembali. Tapi inilah tepatnya at(1)utilitas dibuat untuk:

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

Sulit untuk benar-benar menangkap program berjalan, karena hanya berjalan sekali per menit dan keluar dengan sangat cepat. Untungnya atq(1)utilitas tersebut akan menunjukkan kepada Anda bahwa itu masih berjalan:

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

Dan atrm(1)akan memungkinkan Anda untuk memutus siklus:

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

Anda dapat mengganti 1 minutedengan 1 hour, atau 1 week. Atau berikan 1461 daysuntuk memiliki program yang berjalan setiap 4 tahun sekali.

kotak roti
sumber
2

PowerShell

Saya menyalahgunakan (dan mungkin melanggar) aturan saya sendiri.

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

Diperlukan waktu tak terbatas untuk memulai ulang sendiri.
Itu bisa dibunuh dengan membunuh proses host.

Tunggu dan lihat saja ;)

mikrobia
sumber
5
+1 untuk kreativitas, tetapi -1 untuk kecurangan.
Johannes H.
1
Ha, tetapi apakah "dijamin akan mulai lagi" jika tidak pernah berhenti?
Jason C
Itu sebabnya saya katakan saya mungkin melanggar aturan. Keindahan filosofis ketakterhinggaan yang dapat Anda asumsikan bahwa apa pun dapat terjadi setelah itu. Mesin Turing juga bekerja seperti itu.
mikroba
1
-100 karena saya tidak mendukung Anda memenangkan kontes Anda sendiri, terutama pada masalah teknis, tetapi +101 karena menunggu untuk memulai kembali adalah alasan penundaan terbaik yang pernah ada.
Jason C
Nah, Anda tahu, lalu while true; do sleep 1; doneselimut, bukan?
yo
2

Pesta

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

Simpan ini sebagai repeat.sh di direktori / dan berikan izin eksekusi. Itu bisa dibunuh dengan menghapus file

Ini berfungsi dengan meletakkan entri di crontab untuk menjalankannya 1 menit kemudian.

g.jaket
sumber
2

Basis Visual 6 :)

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

Untuk menjalankan, buat proyek baru, tambahkan modul dengan kode ini, atur objek start-up ke "Sub Main", kompilasi, lalu jalankan executable.


Versi yang lebih mudah dibaca:

Sub Main()
    Call Shell("cmd ping 1.1.1.1 -n 1 -w 3000 > nul && """ & App.Path & "\" & App.EXEName & """")
End Sub
Sikat gigi
sumber
VB6 adalah VB pria sejati. Yang terakhir dari jenisnya!
Jason C
1

HTML / JAVASCRIPT

FILE HTML a.html

<script>window.location = "a.html"</script>
Clyde Lobo
sumber
1

Pesta

Lebih lama dari seharusnya, tapi saya lelah, dan tidak peduli :)

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

Anda mengatakan bahwa itu harus memulai ulang sendiri ketika selesai, Anda tidak secara khusus mengatakan bahwa itu harus dilakukan berulang kali, atau tanpa batas. Juga, Anda mengatakan bahwa seharusnya tidak ada dua kejadian berjalan sekaligus ... tidak akan pernah. ;)

Ada banyak cara untuk melakukan ini. Favorit pribadi saya, akan melakukan sesuatu seperti mengirim paket ke suatu tempat yang jauh, dan kemudian (melalui sejumlah metode), memiliki respons yang memicu proses.

Ian Wizard
sumber
Secara teknis, sleepproses restart ketika selesai
pastebin.com memangkas 0mr8spkT
Jika program itu adalah program yang me -restart sendiri , maka itu tersirat bahwa ia harus melakukannya tanpa batas waktu - jika tidak restart sesuatu yang bukan dirinya sendiri.
Jason C
@Jason C: Tanpa terlalu filosofis, sejauh mungkin, itu akan restart sendiri. Kita bisa memperdebatkan betapa rumitnya untuk benar-benar memulai kembali sendiri , tetapi saya pikir itu jauh melampaui apa yang penulis maksudkan. Padahal, jika Anda ingin benar-benar memulai ulang sendiri, maka itu mungkin akan menjadi sesuatu yang menggunakan goto, atau JMP, atau apa pun yang membangun bahasa Anda mungkin menawarkan, untuk kembali ke awal, jadi itu "memulai kembali" sendiri. Kalau tidak, itu hanya mengeksekusi sesuatu yang jelas seperti itu sendiri. Tetapi kemudian seseorang mungkin akan mengambil masalah bahwa itu tidak benar-benar memulai kembali. Jadi saya ngelantur.
Ian Wizard
1

Android: Alarm akan memulai kembali Aktivitas setelah 1 detik

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

}
kawat67
sumber
1

Lingkungan 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");
    }
}

Anda harus menginstal OpenMPI atau implementasi MPI lainnya. Kompilasi dengan

mpicc -o mpifork mpifork.c

Sekarang saya berpikir tentang itu, tidak ada alasan Anda harus menggunakan mpicc - gcc atau kompiler apa pun yang akan bekerja. Anda hanya perlu memiliki mpirun.

gcc -o mpifork mpifork.c

Untuk menjalankannya, Anda mungkin harus memasukkan nama path lengkap, dan menyertakan daftar host. Sebagai contoh, saya menambahkan beberapa entri di / etc / hosts yang semuanya menunjuk ke localhost, dan menjalankannya seperti ini:

/home/phil/mpifork localhost localhost1 localhost2 localhost3 localhost4

Eksekusi harus berada di direktori yang sama pada mesin apa pun yang Anda ingin jalankan ini.


Pada dasarnya, ini mengambil daftar host yang disediakan pada baris perintah, memilih salah satu host, dan meluncurkan executable pada host target dengan argumen yang sama. Jika semuanya berjalan dengan sempurna, mpirun akan memanggil dirinya berulang-ulang pada mesin yang berbeda (atau mesin yang sama jika Anda hanya menyediakan 'localhost'. Dapat dieksekusi sendiri (mpifork) tidak berakhir - setelah menelepon execvp, itu tidak lagi mengeksekusi pada mesin pertama.

Jika Anda ingin menjadi jahat, Anda bisa membuat peluncuran ini di setiap mesin, dengan memasukkan daftar lengkap host yang disediakan pada baris perintah args. Itu akan menelurkan salinan sendiri pada setiap mesin, berulang-ulang - sebuah forkbomb cluster.

Namun, dalam formulir ini, saya cukup yakin ini memenuhi aturan.

milinon
sumber
1

JavaScript

Tanpa "pergi ke jaringan" bila tidak diperlukan :-) Penjadwalan loop acara JavaScript memungkinkan kita untuk menulis program yang memenuhi persyaratan yang diberikan dengan sangat mudah:

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

Ini "me-restart" programfungsi dengan kecepatan 10 kali per detik. Ini dijamin oleh sifat JavaScript bahwa hanya satu tugas akan berjalan pada saat yang sama, dan itu tidak "restart lingkungan" seperti pada "memuat ulang halaman".

Bergi
sumber
0

Perakitan x86

Tidak sepenuhnya yakin ini cocok dengan kriteria Anda karena tidak menghasilkan proses baru, tapi ini dia.

Program akan menampilkan kotak pesan, mengalokasikan sebagian memori, menyalin bagian kodenya sendiri ke memori yang dialokasikan, dan kemudian melompat ke lokasi tersebut memulai siklus berulang. Itu harus berjalan sampai malloc gagal.

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'

Disusun dengan fasme.

Oscar
sumber
4
Karena ini adalah bagian dari program Anda untuk memanggil kode yang baru disalin, maka secara teknis program Anda tidak pernah selesai sama sekali.
microbian
6
Dari sudut pandang tingkat rendah, hal yang sama dapat dikatakan untuk semua program di sini. :-)
Brian Knoblauch
@BrianKnoblauch saya tidak setuju. Jawaban yang paling menarik di sini tampaknya mengubah lingkungan sistem sehingga salinan baru dari proses dimulai beberapa saat setelah yang pertama terbunuh. Sebagai contoh, saya akan berpikir bahwa menciptakan pekerjaan chron untuk menjalankan proses di masa depan akan menjadi cara yang baik untuk membiarkan proses tersebut benar-benar mati, kemudian dimulai kembali.
Kevin - Reinstate Monica
2
@BrianKnoblauch Tidak juga. Proses adalah konstruksi sistem operasi (yang saat ini - seperti sejak munculnya mode terproteksi pada 286 pada 1982 - juga didukung oleh perangkat keras melalui ruang alamat virtual dan memori yang dilindungi). Ketika itu berakhir, semua info itu hilang. Meskipun tidak dinyatakan secara eksplisit dalam tantangan, saya menganggap semangat tantangan berarti bahwa "mulai ulang" menyiratkan bahwa ID proses baru diberikan.
Jason C
Yah, saya akan memberi +1 jika Anda berhasil membebaskan memori di jalan (tolong ping saya @setelah Anda berhasil, karena saya kemungkinan tidak akan mengawasi itu).
yo
0

Linux pemula baru

Mengingat pembacaan pertanyaan yang paling ketat, saya pikir ini tidak mungkin. Intinya adalah meminta program untuk memulai secara spontan dengan bantuan tidak ada program yang sedang berjalan lainnya.

Ada beberapa jawaban berbasis atdan chron, tetapi dengan pembacaan yang ketat, atddan anacronmerupakan program tambahan yang berjalan sepanjang waktu, sehingga dapat didiskualifikasi.

Pendekatan terkait, tetapi level yang sedikit lebih rendah adalah menggunakan Linux init. Sebagai root, tambahkan file .conf ini ke /etc/init/:

deskripsi "selamanya"

mulai dari runlevel [2345]
berhenti di runlevel [! 2345]

respawn

eksekutif tidur 10

Kemudian initbaca kembali file .conf-nya:

sudo telinit 5

Ini akan memulai sleepproses yang akan hidup selama 10 detik, lalu keluar. initkemudian akan respawn sleepsetelah mendeteksi yang sebelumnya telah pergi.

Tentu saja ini masih digunakan initsebagai program pelengkap. Anda bisa berargumen bahwa itu initadalah ekstensi logis dari kernel dan akan selalu tersedia di Linux apa pun.

Jika ini tidak dapat diterima, maka saya kira hal tingkat bawah berikutnya yang harus dilakukan adalah membuat modul kernel yang respawns proses userspace (tidak yakin betapa mudahnya itu). Di sini dapat diperdebatkan bahwa kernel bukanlah suatu proses, dan karenanya bukan suatu program (tambahan). Di sisi lain, kernel adalah program yang berdiri sendiri, dari sudut CPU.

Trauma Digital
sumber
-1

TI-BASIC: 5 karakter

sebut itu prgmA

:prgmA
scrblnrd3
sumber
Saya bisa menghitung 6 karakter. Apakah ada yang spesial tentang penghitungan ukuran program TI-BASIC?
pastebin.com memangkas 0mr8spkT
Ini :hanyalah awal dari simbol garis setiap kali Anda pemrograman dalam TI-dasar. Ini bukan sesuatu yang Anda ketik, itu hanya ada di editor.
scrblnrd3
Saya mengerti, terima kasih atas informasinya
pastebin.com memangkas 0mr8spkT
Bukankah itu permohonan rekursif? Cobalah menambah Adan menggunakan nilai sebagai kasing, Anda akan melihatnya keluar pada akhirnya.
ζ--
Ya, semua variabel global dalam ti-basic, jadi saya tidak yakin. Mungkin
scrblnrd3