Một chương trình kết thúc nhưng không bao giờ kết thúc [đóng]


35

Viết chương trình tự khởi động lại khi kết thúc.

Không nên có nhiều hơn một phiên bản của chương trình đang chạy cùng một lúc. Thậm chí không trong một khoảnh khắc nhỏ nhất của thời gian.

Bạn có thể bỏ qua bất kỳ trường hợp nào được người dùng bắt đầu thủ công trong chu kỳ của bạn. Nhưng mã của bạn không nên làm điều đó trong chu kỳ khởi động lại của bạn.

Chương trình có thể bắt đầu sau bất kỳ khoảng thời gian nào, miễn là nó được đảm bảo rằng nó sẽ bắt đầu lại.

Cách duy nhất để dừng chu trình là giết quá trình.

Giải pháp của bạn không nên liên quan đến việc khởi động lại môi trường (trong đó chương trình đang chạy, bao gồm HĐH, máy, VM, shell, v.v.). Chỉ chương trình của bạn được phép khởi động lại.


11
Đây không phải là những gì execlàm trong linux?
mniip

11
Tôi hơi lười viết nó ngay bây giờ, nhưng bài nộp của tôi sẽ là (đối với windows): "Chỉnh sửa sổ đăng ký để chương trình của tôi khởi động khi khởi động. Chạy shutdown -r -t 0 -f".
Cruncher

3
Giết chết quá trình sẽ không giết chết chu kỳ của bạn mặc dù.
microbian

19
Tôi mới nhận ra: nếu tôi muốn viết virus và không biết làm thế nào, tôi có thể 1) truy cập StackOverflow, hỏi làm thế nào. Nhận sự ghét từ mọi người và có lẽ câu hỏi sẽ được đóng lại. Hoặc 2) Đi đến mã golf, hỏi người khác cách họ làm điều đó. Nhận một số câu trả lời sáng tạo để lựa chọn và câu hỏi rất phổ biến, nó được đưa vào danh sách "nóng" trên toàn mạng. Mua ha ha ha ha.
rumtscho

5
@rumtscho Bạn biết đấy, đó là một chiến lược chung tốt. Được rồi, đối với thử thách tiếp theo của tôi, hãy xem ai có thể viết phần sụn nhỏ nhất cho thiết bị nguyên mẫu ngồi trên bàn của tôi đáp ứng tất cả các yêu cầu trong tài liệu được liên kết. Để thêm gia vị, điều này phải được thực hiện trước 8 giờ sáng thứ Hai. Đi!
Jason C

Câu trả lời:


50

Kịch bản Bash, 3 ký tự (Ngắn nhất, có thể là thanh lịch nhất, mặc dù phải thừa nhận gây tranh cãi)

$0&

Đơn giản chỉ cần đặt một thể hiện mới của chính nó trong nền (quy trình mới), sau đó thoát. Phiên bản mới có khả năng sẽ vẫn còn trong hàng đợi chạy lịch trình cho đến khi phiên bản trước được thực hiện.

Cảnh báo - điều này thật khó kill, vì PID liên tục thay đổi. Tạm thời đổi tên tệp script có lẽ là cách đơn giản nhất để phá vỡ chu kỳ.

Một hệ thống lõi đơn được giả định. Tất nhiên điều này không thực tế với Linux trên phần cứng kim loại hiện đại, nhưng nó có thể dễ dàng cấu hình khi chạy trong VM. Chúng tôi có thể có thể đạt được một mẹo tương tự bằng cách sử dụng taskset, nhưng điều đó sẽ làm giảm tác động của giải pháp 3 char.

Câu trả lời này uốn cong các quy tắc một chút ở chỗ nó áp dụng một ý nghĩa cụ thể của "chạy". Sẽ có những thời điểm khi quy trình mới được chỉnh sửa fork()và quy trình cũ vẫn còn tồn tại - tức là có thể quan sát nhiều hơn một PID. Tuy nhiên, quy trình mới sẽ được đặt vào hàng đợi chạy lịch trình của Linux để chờ chu kỳ CPU, trong khi quy trình hiện tại sẽ tiếp tục thực thi. Tại thời điểm này, tất cả những gì cần phải được thực hiện bởi quy trình hiện tại là dành cho bashchính nó exit(). Điều này sẽ mất một khoảng thời gian hữu hạn, mặc dù tôi khá tự tin rằng nó sẽ được thực hiện trước khi lượng tử thời gian / lịch trình hiện tại được thực hiện. Bằng chứng hỗ trợ là thực tế rằngbash khởi động và tắt sau 2ms trên máy ảo của tôi:

$ thời gian bash -c:

0m0.002s thực
người dùng 0m0.000s
sys 0m0.000s
$ 

Bằng chứng hỗ trợ thêm rằng quy trình mới không thực sự chạy cho đến khi quy trình trước được thực hiện có thể được nhìn thấy trong straceđầu ra:

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

Trong đầu ra, chúng ta thấy quá trình ban đầu có PID 6929. Chúng ta có thể thấy fork()cuộc gọi (thực tế clone()), trả về một PID mới 6930. Tại thời điểm này có 2 PID, nhưng chỉ 6929 hiện đang chạy:

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.031804 rt_sigprocmask (SIG_BLOCK, NULL, [], 8) = 0
6929 12: 11: 01.031841 đọc (255, "", 4) = 0
6929 12: 11: 01.031907 exit_group (0) =?
6930 12: 11: 01.032016 đóng (255) = 0
6930 12: 11: 01.032052 rt_sigprocmask (SIG_SETMASK, [], NULL, 8) = 0

straceSản lượng đầy đủ ở đây.

Chúng ta có thể thấy rằng 6930 không thực hiện bất kỳ cuộc gọi hệ thống nào cho đến khi 6929 hoàn thành. Thật hợp lý khi cho rằng điều này có nghĩa là 6930 hoàn toàn không chạy cho đến khi 6929 được thực hiện. Các perftiện ích sẽ là cách cuối cùng để chứng minh điều này.


21
"khởi động lại ..., sau đó thoát", vì vậy nhiều hơn một phiên bản đang chạy cùng một lúc?
microbian

4
"... trên lõi đơn" - vâng, tôi cũng sẽ đoán như vậy. Trên nhiều lõi, bạn có thể thấy nhiều thứ.
blabla999

3
Nếu điều này được gắn thẻ code-golf, thì điều này chắc chắn sẽ thắng! +1
John Odom

3
@DigitalTrauma Bạn đang đưa ra những giả định rất lớn về việc mất bao lâu để bash tự tắt. top không cho bạn biết gì - nó chỉ cập nhật một lần trong vài (vài chục) giây nhưng bạn sẽ sinh ra nhiều quy trình mỗi giây.
David Richerby

2
@DavidR Richby - bạn hoàn toàn đúng - topkhông phải là công cụ phù hợp để sử dụng ở đây. Tuy nhiên, tôi thấy rằng time bash -c :chỉ mất 2ms trên máy ảo Ubuntu của mình, vì vậy tôi không nghĩ rằng nó không hợp lý để mong đợi bashhoàn thành việc tắt máy trước khi lượng tử lập lịch của nó được thực hiện.
Chấn thương kỹ thuật số

26

Giải pháp 1

PHP, 32 ký tự

Nó gửi tiêu đề và sau đó nó dừng lại. Sau 3 giây, trang được tải lại.

tập tin a.php

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

Điều này có thể được dừng lại bằng cách chấm dứt việc thực thi trang trước khi các tiêu đề được gửi, hoặc đơn giản bằng cách giết trình duyệt.


Giải pháp 2

PHP, 2 trang

Hãy xem xét hai tập tin hai chương trình khác nhau. Hai tập tin nằm trong cùng một thư mục.

tập tin a.php

header("Location:b.php");

tập tin b.php

header("Location:a.php");

Chấm dứt một trong các trang trước khi các tiêu đề được gửi chấm dứt chương trình (cũng giết trình duyệt hoạt động).

Đây là chương trình tương tự trong

ASP.NET

tập tin a.aspx

Response.Redirect("b.aspx")

tập tin b.aspx

Response.Redirect("a.aspx")

1
Đó là một giải pháp tốt. Tôi hy vọng những người khác đến với câu trả lời khác nhau hơn thế này. Đó là lý do tại sao tôi giữ nó như một cuộc thi nổi tiếng.
microbian

Cho dù câu trả lời tải lại 3 giây của bạn có hợp lệ hay không, tôi để lại cho các chuyên gia php. Tôi nghĩ rằng nó có thể hợp lệ, bởi vì đó là trình duyệt đang chờ đợi chứ không phải php của bạn (tôi không phải là chuyên gia).
microbian

1
Mặc dù về mặt kỹ thuật, PHP được chạy như một mô-đun của máy chủ web và máy chủ web của bạn không khởi động lại, tôi nghĩ rằng nó hợp lệ nếu bạn coi tệp .php là tập lệnh và tập lệnh được chạy nhiều lần.
TwiNight

@TwiNight Cảm ơn bạn đã phản hồi, tôi đánh giá cao nó :)
Vereos

2
Đối với giải pháp thứ hai của bạn, trình duyệt sẽ không phát hiện ra vòng lặp chuyển hướng và tự dừng lại chứ? thedan1984.com/wp-content/uploads/2012/02/ Khăn
Ajedi32

19

sh

echo $PWD/$0 | at tomorrow

Điều này sẽ hoạt động trên bất kỳ hệ thống tương thích Posix.

Để giết nó, xóa tập tin hoặc sử dụng atrm.


17

bash

exec "$0"

execthay thế vỏ mà không tạo ra một quy trình mới. Điều này đảm bảo rằng không thể có trường hợp thứ hai.


1
Tốt hơn nên đặt nó vào ~/.bash_profile!
yegle

@yegle: $0-bashkhi .bash_profilecó nguồn gốc, do đó sẽ chỉ dẫn đến một lỗi cú pháp.
Dennis

Rất tiếc, bạn đã đúng.
yegle

exec ${0##-}trong ~/.bash_profilecác tác phẩm :-)
yegle 31/03 '

14

Bộ lập lịch tác vụ Windows (Bản địa)

C ++. Một cơn ác mộng của lập trình COM. Đáp ứng mọi yêu cầu thử thách.

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

}

Biên dịch với MSVC (hoặc MinGW GCC nếu bạn có tất cả các phụ thuộc).

Chương trình sẽ bắt đầu và đăng ký tác vụ một lần với bộ lập lịch tác vụ Windows để tự khởi động 5 giây sau (Bảng điều khiển -> Công cụ quản trị -> Trình lập lịch tác vụ để xem, tác vụ được đặt tên là "Restarter"). Chương trình sẽ tạm dừng trong 5 giây để cho bạn cơ hội giết nó trước khi nó tạo ra nhiệm vụ.

Yêu cầu thách thức:

  • Bắt đầu lại khi kết thúc. Vâng. Nhiệm vụ được lên lịch ngay trước khi thoát khỏi chương trình.

  • Không quá một phiên bản của chương trình đang chạy cùng một lúc. Vâng. Chương trình thoát hoàn toàn và không chạy trong 5 giây. Nó được bắt đầu bởi lịch trình.

  • Bạn có thể bỏ qua bất kỳ trường hợp nào được người dùng bắt đầu thủ công trong chu kỳ của bạn. Có, như là một tác dụng phụ của việc sử dụng một tên nhiệm vụ không đổi.

  • Miễn là nó được đảm bảo rằng nó bắt đầu lại. Có, với điều kiện Trình lập lịch tác vụ đang chạy (nó có trong cấu hình Windows tiêu chuẩn).

  • Cách duy nhất để dừng chu trình là giết quá trình. Có, quá trình có thể bị giết trong cửa sổ 5 giây trong khi nó đang chạy. Chương trình xóa tác vụ trước thời gian trễ 5 giây, giết nó vào lúc này sẽ không để lại một nhiệm vụ đi lạc trong lịch trình.

  • Giải pháp của bạn không nên liên quan đến việc khởi động lại môi trường Có.

Nhân tiện, nếu có ai từng thắc mắc tại sao các ứng dụng Windows từng không ổn định như vậy (trước sự ra đời của .NET và C #), thì đây là một lý do tại sao. Số lượng xử lý lỗi cần thiết (tôi đã bao gồm nó), quản lý tài nguyên và mức độ chi tiết sẽ thiết lập các tình huống rất dễ xảy ra lỗi nếu một lập trình viên thậm chí hơi lười biếng (đoạn mã trên cực kỳ lười biếng).

Một cách khác dễ dàng hơn và ngắn hơn là gọi scht task.exe. Tôi cũng đã gửi một phiên bản với tập lệnh .BAT .


13

BBC BASIC - một sự tôn vinh cho Tuần tra tuyết

Trình giả lập tại bbcbasic.co.uk

Đây là một chút khác nhau. Nó in một đoạn của bài hát "Run" và phát một đoạn hợp âm của các hợp âm để bạn có thể hát theo. Nó được truyền cảm hứng bởi thực tế là lệnh thực thi (và do đó là dòng cuối cùng của chương trình) tất nhiên là CHẠY.

Tất cả các biến được xóa khi bắt đầu chương trình, do đó, nó sẽ lấy màu màn hình bị bỏ lại bởi lần lặp trước để quyết định câu nào sẽ được in tiếp theo.

    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 (dựng phim của 4 ảnh chụp màn hình khác nhau)

enter image description here


+1 cho giải pháp màu thay thế "bộ nhớ chia sẻ".
Julian H.

11

HTML / JavaScript:

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

Mã kích hoạt việc phá hủy trang mà nó đang chạy, sau đó tạo lại một phiên bản khác của chính nó khi trình duyệt tải trang một lần nữa.

AFAIK, lối thoát duy nhất là giết tab mà trang đang chạy.

EDIT: theo yêu cầu phổ biến, mã HTML5 hợp lệ:

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

@JasonC Tôi không đồng ý. Tôi nghĩ rằng các trang hợp lý nên tuân thủ các thông số kỹ thuật, nhưng các cuộc thi phổ biến được cho là hợp lý, phải không? : D so +1, tôi thực sự thích cái này.
yo '

10

C

Chương trình này hoạt động giống như rất nhiều phần mềm độc hại. Ngay trước khi đóng, nó tạo một tập lệnh shell trong thư mục / tmp. Nó giả mạo để bắt đầu tập lệnh shell, cho phép chương trình gốc đóng và hủy bỏ PID gốc. Sau một khoảng thời gian ngắn (2 giây), tập lệnh shell bắt đầu một quy trình mới với chương trình. Để đơn giản, vị trí chương trình được nối cứng là '/ 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]);
}

Mỗi lần chỉ có một quá trình 'không bao giờ' chạy. Mỗi quy trình mới có một PID mới. Cách dễ nhất để giết cái này là xóa tệp thực thi. Nếu bạn muốn làm cho nó ác tính hơn, bạn có thể sao chép cả tập lệnh thực thi và tập lệnh để đảm bảo có nhiều bản sao trên chương trình trên đĩa bất cứ lúc nào.


1
Tôi đang mong đợi để xem câu trả lời sáng tạo hơn. Xem ý kiến ​​cho câu hỏi về 'chương trình bổ sung'. Đối với tôi, một chương trình bổ sung chỉ là một phần trong chương trình của bạn.
microbian

4
Ngã ba có nghĩa là bạn sẽ có hai phiên bản của quy trình đang chạy cùng một lúc, ngay cả khi chúng đang làm những việc khác nhau.
Barry Fruitman

@BarryF sinhman dễ tránh, mặc dù, bằng cách thực sự sử dụng hai thực thi khác nhau. Đó là hợp lệ sau đó, nhưng cách ít thanh lịch.
Julian H.

Tôi cho rằng bạn có thể sử dụng system()nếu các quy tắc không tính một fork + exec thành /bin/shmột chương trình bổ sung.
Jason C

10

Perl

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

Kịch bản lệnh đưa ra một lệnh hệ thống để tự giết mình và đưa kết quả vào một thể hiện khác của chính nó. Trình thông dịch Perl được sử dụng để giết, vì lý do đa nền tảng.

Ngăn chặn sự điên rồ bằng cách xóa kịch bản.


7

Cơ bản 8 bit

1L.:R.

Mã thông báo tới:

1 LIST : RUN

Trong nội bộ, nó đang xóa các cấu trúc bên trong, về cơ bản xóa sạch chương trình, trước khi chạy lại nó khỏi danh sách.

Điều này về cơ bản khác với:

1L.:G.1

Mã thông báo nào:

1 LIST : GOTO 1

Đây là một vòng lặp vô hạn cơ bản. Khi bạn chạy chúng, bạn sẽ thấy sự khác biệt về tốc độ (đầu tiên là chậm hơn).


Tôi không rõ tại sao "danh sách" trong khi thực hiện chương trình sẽ xóa mọi cấu trúc xen kẽ. Tôi nghĩ Atari có bộ đệm bàn phím, vì vậy người ta có thể liệt kê chương trình, nhét các tổ hợp phím để chạy nó và thực hiện "mới" với con trỏ được định vị để "gõ lại" nó.
supercat

@supercat - DANH SÁCH không, CHẠY.

Theo logic đó, người ta có thể bỏ qua "DANH SÁCH". Mặt khác, nếu chương trình nhét bộ đệm bàn phím, với một vài lần quay trở lại, hãy đặt "MỚI" theo sau là chương trình và "CHẠY" ở đúng vị trí trên màn hình, đặt con trỏ và thoát ra, nó sẽ thực sự tự xóa và tự động gõ lại.
supercat

@supercat - không có LIST, bạn sẽ không thấy nó chạy. Tôi đã chọn LISTbởi vì nó có đầu vào ngắn nhất L.. Tôi thích ý tưởng đặt nó vào bộ đệm bàn phím, nó chắc chắn đủ ngắn!

Tôi có nhớ chính xác rằng Atari, giống như các máy Commodore, đọc văn bản khỏi màn hình khi bạn ấn Returnkhông? Làm thế nào lớn là bộ đệm bàn phím? Trên VIC-20 và C64, đó là mười byte. Một chương trình chọc đủ để tải bộ đệm bàn phím có thể sẽ không vừa với bộ đệm bàn phím, nhưng tôi đã viết các chương trình sẽ tự sửa đổi bằng cách in các thay đổi trên màn hình theo sau RUNvà nhét một vài lần Returnnhấn phím. Những thứ như vậy đặc biệt hữu ích trên 64 vì nó không có lệnh [IIRC] INmà Atari có để hợp nhất các dòng vào một chương trình.
supercat

5

Trên Mainframe của IBM đang chạy z / OS, bạn chạy một tiện ích sao chép tập dữ liệu (tệp) sang tập dữ liệu khác (tệp). Đầu vào là nguồn của JCL (Ngôn ngữ kiểm soát công việc) mà bạn đã gửi để khiến nó chạy. Đầu ra là Bộ đọc nội bộ (INTRDR). Bạn cũng sẽ cần đảm bảo rằng hệ thống của bạn không cho phép chạy nhiều tên công việc giống hệt nhau. Tốt để sử dụng một lớp công việc chỉ có một người khởi tạo (nơi mà JOB có thể chạy theo đợt).

Không có bộ vi xử lý nào liên quan (trong z / OS), do đó không đặt được thử thách.

Bạn tạm dừng quá trình bằng cách xả nước và / hoặc xả nước. Nếu có gì đó không ổn, bằng cách xả nước và / hoặc xả nước, chửi thề, đá, cố gắng khởi động ấm áp và cuối cùng bằng khởi động lạnh hoặc nhấn Nút Big Red (và bắn lập trình viên).

Tôi có thể đã phóng đại trên đường đi, nhưng đừng thử điều này tại nơi làm việc ...

Ví dụ sử dụng SORT. Thông tin chi tiết trên thẻ JOB rất phụ thuộc vào trang web. Chính sách trang web có thể cấm hoặc ngăn chặn việc sử dụng INTRDR. Một lớp cụ thể có thể được yêu cầu để sử dụng INTRDR. Nếu chính sách trang web của bạn cấm sử dụng, đừng sử dụng nó trừ khi bạn muốn mang đồ đạc đi dạo trong hộp các tông.

Mặc dù có những cách sử dụng tốt cho INTRDR, nhưng không sử dụng nó cho mục đích này . Bạn thậm chí sẽ không có cơ hội để có được hộp của bạn.

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

Các tiện ích khác có sẵn. Một chương trình nhanh cũng sẽ dễ dàng thực hiện, chỉ cần đọc một tệp, viết một tệp.

Nếu bạn muốn một ví dụ về điều này sai, hãy thử: http://ibmmainframes.com/viewtopic.php?p=282414#282414

Cách truyền thống để sao chép tập dữ liệu là sử dụng tiện ích IEBGENER của IBM, như những ám chỉ xấu xí trong nhận xét của họ.

Tuy nhiên, những ngày này, nhiều trang web sẽ có IEBGENER "bí danh" cho ICEGENER. ICEGENER sẽ, nếu có thể, sử dụng DFSORT của IBM (hoặc đối thủ SyncSort của nó) để tạo một bản sao, vì các sản phẩm SORT được tối ưu hóa nhiều hơn cho IO so với IEBGENER.

Tôi chỉ cần loại bỏ người trung gian bằng cách sử dụng SORT.

Nếu bạn làm việc tại một trang web Mainframe của IBM, bạn sẽ biết định dạng của thẻ JOB mà bạn nên sử dụng. Thẻ JOB tối thiểu như tôi đã trình bày, không có nhận xét. Nhận xét sẽ rất quan trọng, chẳng hạn, vì bạn có thể được cho là đang cung cấp thông tin kế toán. Tên công việc có thể sẽ có một định dạng trang web cụ thể.

Một số trang web cấm hoặc ngăn chặn việc sử dụng INTRDR. Hãy nhận biết.

Một số trang web cho phép nhiều công việc có cùng tên chạy cùng một lúc. Hãy nhận biết.

Mặc dù trừ khi bạn là Lập trình viên của Hệ thống, bạn không thể thiết lập một lớp như vậy, bạn nên tìm một lớp chỉ cho phép một người khởi tạo. Cùng với đó, quy trình này khá an toàn - nhưng hãy chắc chắn về việc lớp đang hoạt động như mô tả. Kiểm tra. Không phải với công việc này.

Nếu bạn là Lập trình viên của Hệ thống, bạn biết không được làm bất cứ điều gì ngoài tiền gửi của mình. 'nuff nói.

Với một công việc có cùng tên được cho phép cùng một lúc và một công cụ khởi tạo, đây sẽ là một dòng liên tục bắt đầu / kết thúc công việc bắt đầu / kết thúc công việc tiếp theo - cho đến khi bạn điền vào ống chỉ (một điều xấu khác phải làm) với đầu ra từ hàng ngàn công việc (hoặc hết số công việc). Xem Bảng điều khiển JES để biết thông báo cảnh báo.

Về cơ bản, đừng làm điều này. Nếu bạn làm điều đó, đừng làm điều đó trên máy Sản xuất.

Với một chút quan tâm, tôi sẽ xem xét một Câu trả lời khác về cách thực hiện trên hệ điều hành Mainframe khác của IBM, z / VSE ... z / VSE sử dụng JCL. z / HĐH sử dụng JCL. Họ khác nhau :-)


Ý tưởng có vẻ tốt, nhưng nó không phải là một câu trả lời. Chỉ cho chúng tôi JCL - JOB, EXEC và DD - sau đó sẽ là một câu trả lời.
ugoren

Không thể gửi một công việc trong một thời gian dài, vì vậy tôi không biết phải làm gì. Nếu các phần còn thiếu chỉ là tùy chỉnh cục bộ, thì OK. Nhưng nếu bạn che giấu công cụ để ngăn chặn sự lạm dụng, thì hãy quyết định - đăng thực tế hoặc không đăng gì cả. PS Chúng tôi sử dụng IEBGENERtrở lại sau đó chỉ đơn giản là sao chép.
ugoren

@ugoren Cập nhật thêm, bao gồm giải thích lý do tại sao IEBGENER không được chọn cho tác vụ. Việc xóa văn bản nhận xét trên câu lệnh JOB sẽ cho JCL cần thiết để nó chạy, nhưng JCL đủ để phụ thuộc vào các tiêu chuẩn trang web địa phương, cho công việc để làm việc hoặc cho lập trình viên để tránh bị sa thải.
Bill Woodger

4

Python (72 byte)

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

Tôi có thể làm cho nhỏ hơn tôi đoán. Đầu tiên, bằng cách mã hóa tên của tệp (thay vì sử dụng__file__ ). Nhưng ở đây, bạn có thể đặt mã này vào một tệp và chạy nó, bất kể tên của nó là gì :)


Bạn có thể có thể thay đổi &&để &.
Hosch250

1
Từ khi nào được phép, user2509848?
Rhymoid

Chà, bạn có thể bắt đầu bằng cách xóa khoảng trắng từ
Ry-

6
Vì nó không được gắn thẻ mã golf , tôi sẽ giữ mã như thế này :-)
Maxime Lorant

4

Bộ lập lịch tác vụ Windows (.BAT)

Kịch bản lô Windows. Đáp ứng mọi yêu cầu thử thách.

Theo như tôi có thể thấy đây là giải pháp Windows duy nhất cho đến nay đáp ứng tất cả các yêu cầu và không có phụ thuộc không chuẩn (giải pháp khác của tôi tương tự nhưng yêu cầu biên dịch).

@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

Chương trình hoạt động tương tự như câu trả lời C ++ / COM của tôi .

Chương trình sẽ bắt đầu và đăng ký tác vụ một lần với bộ lập lịch tác vụ Windows để tự khởi động tối đa 60 giây sau (Bảng điều khiển -> Công cụ quản trị -> Trình lập lịch tác vụ để xem, tác vụ được đặt tên là "Restarter"). Chương trình sẽ tạm dừng trong 5 giây để cho bạn cơ hội giết nó trước khi nó tạo ra nhiệm vụ.

Làm cho việc sử dụng dòng lệnh Giao diện lập lịch tác vụ schtasks.exe . Số học trong tập lệnh là để tính toán thời gian bù trong khi vẫn giữ thời gian hợp lệ và ở định dạng HH: MM.

Yêu cầu thách thức:

  • Bắt đầu lại khi kết thúc. Vâng. Nhiệm vụ được lên lịch ngay trước khi thoát khỏi chương trình.

  • Không quá một phiên bản của chương trình đang chạy cùng một lúc. Vâng. Chương trình thoát hoàn toàn và không chạy trong ~ 60 giây. Nó được bắt đầu bởi lịch trình.

  • Bạn có thể bỏ qua bất kỳ trường hợp nào được người dùng bắt đầu thủ công trong chu kỳ của bạn. Có, như là một tác dụng phụ của việc sử dụng một tên nhiệm vụ không đổi.

  • Miễn là nó được đảm bảo rằng nó bắt đầu lại. Có, với điều kiện Trình lập lịch tác vụ đang chạy và scht task.exe có mặt (cả hai đều đúng trong cấu hình Windows mặc định).

  • Cách duy nhất để dừng chu trình là giết quá trình. Có, quá trình có thể bị giết trong cửa sổ 5 giây trong khi nó đang chạy. Chương trình xóa tác vụ trước thời gian trễ 5 giây, giết nó vào lúc này sẽ không để lại một nhiệm vụ đi lạc trong lịch trình.

  • Giải pháp của bạn không nên liên quan đến việc khởi động lại môi trường Có.

Lưu ý: Do giao diện dòng lệnh bị giới hạn, thời gian khởi động lại phải được chỉ định trong vài phút và tác vụ sẽ không khởi động lại trên máy tính xách tay nếu không cắm bộ chuyển đổi AC (xin lỗi).


3

Vỏ Unix

Tôi chưa thấy nhiều giải pháp dựa vào một chương trình không liên quan để khởi động lại nó. Nhưng đây chính xác là những gì at(1)tiện ích được tạo ra cho:

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

Thật khó để bắt chương trình chạy, vì nó chỉ chạy một lần mỗi phút và thoát rất nhanh. May mắn là atq(1)tiện ích sẽ cho bạn thấy rằng nó vẫn đang hoạt động:

$ 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)sẽ cho phép bạn phá vỡ chu kỳ:

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

Bạn có thể thay thế 1 minutebằng 1 hour, hoặc 1 week. Hoặc cung cấp cho nó 1461 daysđể có một chương trình chạy 4 năm một lần.


2

PowerShell

Tôi đang lạm dụng (và có thể phá vỡ) quy tắc của riêng tôi.

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

Phải mất vô số thời gian để tự khởi động lại.
Nó có thể bị giết bằng cách giết quá trình máy chủ.

Cứ chờ xem ;)


5
+1 cho sự sáng tạo, nhưng -1 cho gian lận.
Julian H.

1
Ha, nhưng nó có "đảm bảo rằng nó sẽ bắt đầu lại" nếu nó không bao giờ dừng lại?
Jason C

Đó là lý do tại sao tôi nói tôi có thể phá vỡ quy tắc. Đó là vẻ đẹp triết lý của vô cực mà bạn có thể cho rằng bất cứ điều gì cũng có thể xảy ra sau đó. Máy Turing hoạt động theo cách đó quá.
microbian

1
-100 vì tôi không hỗ trợ bạn chiến thắng cuộc thi của riêng bạn, đặc biệt là về mặt kỹ thuật, nhưng +101 vì chờ đợi nó khởi động lại là lý do chần chừ tốt nhất từ ​​trước đến nay.
Jason C

Chà, bạn biết đấy, sau đó làm while true; do sleep 1; donengơ, phải không?
yo '

2

Bash

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

Lưu cái này dưới dạng repeat.sh trong thư mục / và cho phép nó thực thi. Nó có thể bị giết bằng cách xóa tập tin

Điều này hoạt động bằng cách đặt một mục trong crontab để chạy nó 1 phút sau.


2

Cơ sở trực quan 6 :)

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

Để chạy, tạo một dự án mới, thêm một mô-đun với mã này, đặt đối tượng khởi động thành "Sub Main", biên dịch và sau đó chạy tệp thực thi.


Phiên bản dễ đọc hơn:

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

VB6 là VB của một người đàn ông thực sự. Cuối cùng của loại hình này!
Jason C

1

HTML / JAVASCRIPT

TẬP TIN HTML a.html

<script>window.location = "a.html"</script>

1

Bash

Lâu hơn nó phải thế, nhưng tôi mệt, và không quan tâm :)

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

Bạn nói rằng nó phải tự khởi động lại khi nó kết thúc, bạn không nói cụ thể rằng nó phải làm như vậy nhiều lần, hoặc vô thời hạn. Ngoài ra, bạn nói rằng nó sẽ không bao giờ có hai phiên bản chạy cùng một lúc ... nó sẽ không bao giờ. ;)

Có rất nhiều cách để làm điều này. Yêu thích cá nhân của tôi, sẽ là làm một cái gì đó như gửi một gói ở một nơi xa, và sau đó (thông qua bất kỳ số phương thức nào), có phản hồi kích hoạt quá trình.


Về mặt kỹ thuật, sleepquá trình khởi động lại khi nó kết thúc
pastebin.com chém 0mr8spkT

Nếu chương trình là một chương trình tự khởi động lại , thì nó được ngụ ý rằng nó phải làm như vậy vô thời hạn - nếu không thì nó đang khởi động lại một cái gì đó không phải là chính nó.
Jason C

@Jason C: Không cần quá triết lý, đến mức có thể, nó sẽ tự khởi động lại. Chúng ta có thể tranh luận mức độ phức tạp của việc tự khởi động lại nó , nhưng tôi nghĩ điều đó vượt xa ý nghĩa của tác giả. Mặc dù, nếu bạn muốn nó thực sự tự khởi động lại, thì nó có thể là thứ gì đó sử dụng goto, hoặc JMP, hoặc bất kỳ cấu trúc nào mà ngôn ngữ của bạn có thể cung cấp, để quay lại từ đầu, vì vậy nó sẽ tự "khởi động lại". Mặt khác, nó chỉ thực hiện một cái gì đó giống như chính nó. Nhưng sau đó ai đó có thể sẽ gặp vấn đề mà không thực sự khởi động lại. Thế là tôi lạc đề.
Ian Wizard

1

Android: Báo thức sẽ khởi động lại Hoạt động sau 1 giây

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

Môi trường 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");
    }
}

Bạn phải cài đặt OpenMPI hoặc một số triển khai MPI khác. Biên dịch với

mpicc -o mpifork mpifork.c

Bây giờ tôi nghĩ về nó, không có lý do gì bạn phải sử dụng mpicc - gcc hoặc bất kỳ trình biên dịch nào sẽ hoạt động. Bạn chỉ cần có mpirun.

gcc -o mpifork mpifork.c

Để chạy nó, có lẽ bạn nên bao gồm tên đường dẫn đầy đủ và bao gồm một danh sách các máy chủ lưu trữ. Ví dụ: tôi đã thêm một số mục trong / etc / hosts mà tất cả đều trỏ đến localhost và chạy nó như thế này:

/home/phil/mpifork localhost localhost1 localhost2 localhost3 localhost4

Tệp thực thi phải nằm trong cùng thư mục trên bất kỳ máy nào bạn muốn chạy cái này.


Về cơ bản, cái này lấy danh sách các máy chủ được cung cấp trên dòng lệnh, chọn một trong các máy chủ và khởi chạy chương trình thực thi trên máy chủ đích với cùng các đối số. Nếu mọi thứ diễn ra hoàn hảo, mpirun sẽ tự gọi đi gọi lại trên các máy khác nhau (hoặc cùng một máy nếu bạn chỉ cung cấp 'localhost'. Bản thân thực thi (mpifork) sẽ chấm dứt - sau khi gọiexecvp , nó không còn thực thi trên máy đầu tiên.

Nếu bạn muốn trở thành ác quỷ, thay vào đó bạn có thể thực hiện việc khởi chạy này trên mọi máy, bằng cách bao gồm danh sách đầy đủ các máy chủ được cung cấp trên dòng lệnh trongargs . Điều đó sẽ sinh ra một bản sao của chính nó trên mọi máy, lặp đi lặp lại - một cụm sao.

Tuy nhiên, trong hình thức này, tôi khá chắc chắn rằng điều này đáp ứng các quy tắc.


1

JavaScript

Không cần "truy cập mạng" khi không cần thiết :-) Lập lịch vòng lặp sự kiện của JavaScript cho phép chúng tôi viết các chương trình đáp ứng các yêu cầu đã cho rất dễ dàng:

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

Điều này "khởi động lại" programchức năng với tốc độ 10 lần mỗi giây. Bản chất của JavaScript được đảm bảo rằng chỉ một tác vụ duy nhất sẽ chạy cùng lúc và nó không "khởi động lại môi trường" như trong "tải lại trang".


0

hội x86

Không hoàn toàn chắc chắn điều này phù hợp với tiêu chí của bạn vì nó không sinh ra một quy trình mới, nhưng dù sao thì đây cũng là một quy trình.

Chương trình sẽ hiển thị một hộp thông báo, phân bổ một số bộ nhớ, sao chép phần mã của chính nó vào bộ nhớ được phân bổ và sau đó nhảy đến vị trí đó bắt đầu chu kỳ kết thúc. Nó sẽ chạy cho đến khi malloc thất bại.

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'

Được biên soạn với fasm.


4
Vì nó là một phần trong chương trình của bạn để gọi mã mới được sao chép, nên về mặt kỹ thuật, chương trình của bạn không bao giờ kết thúc.
microbian

6
Từ quan điểm cấp thấp, điều tương tự có thể được nói về tất cả các chương trình ở đây. :-)
Brian Knoblauch

@BrianKnoblauch Tôi không đồng ý. Các câu trả lời thú vị nhất ở đây dường như sửa đổi môi trường hệ thống để một bản sao mới của quy trình được bắt đầu một thời gian sau khi cái đầu tiên bị giết. Ví dụ, tôi sẽ nghĩ rằng việc tạo một công việc chron để chạy quy trình trong tương lai sẽ là một cách tốt để cho quá trình hoàn toàn chết, sau đó được khởi động lại.
Kevin - Tái lập Monica

2
@BrianKnoblauch Không thực sự. Một quy trình là một cấu trúc hệ điều hành (mà ngày nay - như từ sự ra đời của chế độ được bảo vệ trong năm 286 năm 1982 - cũng được hỗ trợ bởi phần cứng thông qua không gian địa chỉ ảo và bộ nhớ được bảo vệ). Khi nó kết thúc, tất cả thông tin đó sẽ biến mất. Mặc dù nó không được nêu rõ ràng trong thử thách, tôi lấy tinh thần của thử thách có nghĩa là "khởi động lại" ngụ ý rằng ID tiến trình mới được chỉ định.
Jason C

Chà, tôi sẽ cho +1 nếu bạn quản lý để giải phóng bộ nhớ trên đường đi (vui lòng ping tôi bằng cách @bạn quản lý, vì tôi có thể sẽ không để mắt đến nó).
yo '

0

Linux mới bắt đầu

Với việc đọc câu hỏi nghiêm ngặt nhất, tôi nghĩ điều này là không thể. Về bản chất, nó đang yêu cầu một chương trình tự khởi động với sự trợ giúp của không có chương trình đang chạy nào khác.

Có một số câu trả lời atchrondựa trên, nhưng với cách đọc nghiêm ngặt nhất, atdanacron là các chương trình bổ sung đang chạy mọi lúc, vì vậy chúng có thể bị loại.

Một cách tiếp cận liên quan, nhưng mức độ thấp hơn một chút là sử dụng Linux init. Với quyền root, hãy thêm tệp .conf này vào/etc/init/ :

mô tả "mãi mãi"

bắt đầu trên runlevel [2345]
dừng lại trên runlevel [! 2345]

hồi sinh

thực hiện giấc ngủ 10

Sau đó đã initđọc lại các tập tin .conf của nó:

sudo telinit 5

Điều này sẽ bắt đầu một sleepquá trình sẽ tồn tại trong 10 giây, sau đó thoát. initsau đó sẽ hồi sinh sleepkhi nó phát hiện ra cái trước đó đã biến mất.

Tất nhiên điều này vẫn được sử dụng initnhư một chương trình bổ sung. Bạn có thể lập luận rằng đó initlà một phần mở rộng hợp lý của kernel và sẽ luôn có sẵn trong bất kỳ Linux nào.

Nếu điều này không được chấp nhận, thì tôi đoán điều tiếp theo ở cấp độ thấp hơn sẽ làm là tạo ra một mô-đun hạt nhân đáp ứng quy trình không gian người dùng (không chắc nó dễ đến mức nào). Ở đây có thể lập luận rằng kernel không phải là một quá trình, và do đó không phải là một chương trình (bổ sung). Mặt khác, kernel là một chương trình theo đúng nghĩa của nó, từ điểm của CPU.


-1

TI-BASIC: 5 ký tự

gọi nó đi prgmA

:prgmA

Tôi có thể đếm 6 ký tự. Có điều gì đặc biệt về việc đếm kích thước chương trình TI-BASIC không?
pastebin.com chém 0mr8spkT

Đây :chỉ là biểu tượng bắt đầu của dòng bất cứ khi nào bạn lập trình trong TI-basic. Đây không phải là thứ bạn nhập vào, nó chỉ có trong trình chỉnh sửa.
Scrblnrd3

Tôi hiểu rồi, cảm ơn vì thông tin
pastebin.com chém 0mr8spkT

Đó không phải là lời gọi đệ quy sao? Hãy thử tăng dần Avà sử dụng giá trị của nó làm trường hợp cơ bản, cuối cùng bạn sẽ thấy nó bước ra.
ζ--

Well all variables are globals in ti-basic, so I'm not sure. It might be
scrblnrd3
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.