如何在运行时打破无限循环?

时间:2022-02-17 08:51:42

Say that I have:

说我有:

b = true;
while(b){}

Is there any way to continue on after this point? Like some way to modify the value of b without stopping and re running the program?

在这一点之后还有什么办法可以继续吗?像某些方法修改b的值而不停止并重新运行程序?

I want to do this as a simple method to pause the program for an unspecified amount of time, that changes all the time.

我想这样做是一种简单的方法,可以在一段不确定的时间内暂停程序,这种方法会一直在变化。

3 个解决方案

#1


You can read the value of b from a data source that is modifiable by the user during runtime.

您可以从运行时可由用户修改的数据源中读取b的值。

This can be anything from a database, a network socket, or simply a file.

这可以是数据库,网络套接字或简单文件。

In this case I would recommend a socket. Below is a very rough, but working, example.

在这种情况下,我会建议一个插座。下面是一个非常粗略但有效的例子。

Once you start the program in Eclipse, you need to open a terminal window and telnet localhost 10008.

在Eclipse中启动程序后,需要打开终端窗口并telnet localhost 10008。

The accepted commands via the socket are:

通过套接字接受的命令是:

<numeric value> = pause the app for that amount of milliseconds

<数值> =暂停应用程序的毫秒数

BYE = close the socket

BYE =关闭套接字

STOP = completely stop the app

STOP =完全停止应用程序

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class RuntimePause extends Thread {
    protected static boolean appRunning = true;
    protected Socket clientSocket;

    private long pause = 0;

    public static void main(String[] args) throws IOException {

        RuntimePause app = new RuntimePause();
        app.start();

        while (true) {
            app.listen();
        }

    }

    public void run() {

        while (appRunning) {

            System.out.println("App running...");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }

            if (pause > 0) {
                System.out.println("App pausing for " + pause + " ms");
                try {
                    Thread.sleep(pause);
                } catch (InterruptedException e) {
                }
                pause = 0;
            }

        }
    }

    public void listen() {

        ServerSocket serverSocket = null;

        try {
            serverSocket = new ServerSocket(10008);
            System.out.println("Connection Socket Created");
            try {
                while (appRunning) {
                    System.out.println("Waiting for Connection");
                    new NetworkSocket(serverSocket.accept());
                }
            } catch (IOException e) {
                System.err.println("Accept failed.");
                System.exit(1);
            }
        } catch (IOException e) {
            System.err.println("Could not listen on port: 10008.");
            System.exit(1);
        } finally {
            try {
                serverSocket.close();
            } catch (IOException e) {
                System.err.println("Could not close port: 10008.");
                System.exit(1);
            }
        }
    }

    public class NetworkSocket extends Thread {

        public NetworkSocket(Socket clientSoc) {
            clientSocket = clientSoc;
            start();
        }

        public void run() {
            {
                System.out.println("New Communication Thread Started");

                try {
                    PrintWriter out = new PrintWriter(
                            clientSocket.getOutputStream(), true);
                    BufferedReader in = new BufferedReader(
                            new InputStreamReader(clientSocket.getInputStream()));

                    String inputLine;

                    while ((inputLine = in.readLine()) != null) {
                        System.out.println("Received: " + inputLine);

                        // Client sent a pause command
                        try {
                            long pauseCommand = Long.parseLong(inputLine);
                            pause = pauseCommand;
                            out.println("OK, pausing for " + inputLine + " ms");
                        } catch (NumberFormatException e) {
                            //
                        }

                        // Client wishes to terminate connection to socket
                        if (inputLine.equals("BYE")) {
                            out.println("OK, bye!");
                            break;
                        }

                        // Client orders the app to stop
                        if (inputLine.equals("STOP")) {
                            out.println("OK, stopping!");
                            System.exit(1);
                        }
                    }

                    out.close();
                    in.close();
                    clientSocket.close();
                } catch (IOException e) {
                    System.err.println("Problem with Communication Server");
                    System.exit(1);
                }
            }
        }
    }
}

By the way, this code is not production ready. It simply serves as a example of how you can approach the problem. You want to ensure that the variables are accessed in a thread-safe way.

顺便说一句,这段代码不是生产就绪的。它只是作为如何解决问题的一个例子。您希望确保以线程安全的方式访问变量。

#2


BOOL b;

- (void)viewDidLoad {
    [super viewDidLoad];

    //Create a button
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    //Which is black
    button.backgroundColor = [UIColor blackColor];
    //Add it to the view
    [self.view addSubview:button];
    //When you press the button, do stopPrintingB method
    [button addTarget:self action:@selector(stopPrintingB) forControlEvents:UIControlEventTouchUpInside];


    b = true;
    /*
     * This is a GCD means not in the main thread
     * If you make while(b) in the main thread
     * the program will not do stopPrintingB method until the main thread is free
     */
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        while (b) {
            NSLog(@"printing b");
        }
    });
}

//make b false and stopPrintingB
- (void)stopPrintingB
{
    b = false;
}

#3


If you run your program in debug mode you can inject code that will break the loop. In the example posted just change:

如果在调试模式下运行程序,则可以注入会破坏循环的代码。在发布的示例中只需更改:

b = true;
while(b){}

to:

b = true;
while(b){b=false;}

Then save the file and the loop will be broken.

然后保存文件,循环将被破坏。

#1


You can read the value of b from a data source that is modifiable by the user during runtime.

您可以从运行时可由用户修改的数据源中读取b的值。

This can be anything from a database, a network socket, or simply a file.

这可以是数据库,网络套接字或简单文件。

In this case I would recommend a socket. Below is a very rough, but working, example.

在这种情况下,我会建议一个插座。下面是一个非常粗略但有效的例子。

Once you start the program in Eclipse, you need to open a terminal window and telnet localhost 10008.

在Eclipse中启动程序后,需要打开终端窗口并telnet localhost 10008。

The accepted commands via the socket are:

通过套接字接受的命令是:

<numeric value> = pause the app for that amount of milliseconds

<数值> =暂停应用程序的毫秒数

BYE = close the socket

BYE =关闭套接字

STOP = completely stop the app

STOP =完全停止应用程序

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class RuntimePause extends Thread {
    protected static boolean appRunning = true;
    protected Socket clientSocket;

    private long pause = 0;

    public static void main(String[] args) throws IOException {

        RuntimePause app = new RuntimePause();
        app.start();

        while (true) {
            app.listen();
        }

    }

    public void run() {

        while (appRunning) {

            System.out.println("App running...");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }

            if (pause > 0) {
                System.out.println("App pausing for " + pause + " ms");
                try {
                    Thread.sleep(pause);
                } catch (InterruptedException e) {
                }
                pause = 0;
            }

        }
    }

    public void listen() {

        ServerSocket serverSocket = null;

        try {
            serverSocket = new ServerSocket(10008);
            System.out.println("Connection Socket Created");
            try {
                while (appRunning) {
                    System.out.println("Waiting for Connection");
                    new NetworkSocket(serverSocket.accept());
                }
            } catch (IOException e) {
                System.err.println("Accept failed.");
                System.exit(1);
            }
        } catch (IOException e) {
            System.err.println("Could not listen on port: 10008.");
            System.exit(1);
        } finally {
            try {
                serverSocket.close();
            } catch (IOException e) {
                System.err.println("Could not close port: 10008.");
                System.exit(1);
            }
        }
    }

    public class NetworkSocket extends Thread {

        public NetworkSocket(Socket clientSoc) {
            clientSocket = clientSoc;
            start();
        }

        public void run() {
            {
                System.out.println("New Communication Thread Started");

                try {
                    PrintWriter out = new PrintWriter(
                            clientSocket.getOutputStream(), true);
                    BufferedReader in = new BufferedReader(
                            new InputStreamReader(clientSocket.getInputStream()));

                    String inputLine;

                    while ((inputLine = in.readLine()) != null) {
                        System.out.println("Received: " + inputLine);

                        // Client sent a pause command
                        try {
                            long pauseCommand = Long.parseLong(inputLine);
                            pause = pauseCommand;
                            out.println("OK, pausing for " + inputLine + " ms");
                        } catch (NumberFormatException e) {
                            //
                        }

                        // Client wishes to terminate connection to socket
                        if (inputLine.equals("BYE")) {
                            out.println("OK, bye!");
                            break;
                        }

                        // Client orders the app to stop
                        if (inputLine.equals("STOP")) {
                            out.println("OK, stopping!");
                            System.exit(1);
                        }
                    }

                    out.close();
                    in.close();
                    clientSocket.close();
                } catch (IOException e) {
                    System.err.println("Problem with Communication Server");
                    System.exit(1);
                }
            }
        }
    }
}

By the way, this code is not production ready. It simply serves as a example of how you can approach the problem. You want to ensure that the variables are accessed in a thread-safe way.

顺便说一句,这段代码不是生产就绪的。它只是作为如何解决问题的一个例子。您希望确保以线程安全的方式访问变量。

#2


BOOL b;

- (void)viewDidLoad {
    [super viewDidLoad];

    //Create a button
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    //Which is black
    button.backgroundColor = [UIColor blackColor];
    //Add it to the view
    [self.view addSubview:button];
    //When you press the button, do stopPrintingB method
    [button addTarget:self action:@selector(stopPrintingB) forControlEvents:UIControlEventTouchUpInside];


    b = true;
    /*
     * This is a GCD means not in the main thread
     * If you make while(b) in the main thread
     * the program will not do stopPrintingB method until the main thread is free
     */
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        while (b) {
            NSLog(@"printing b");
        }
    });
}

//make b false and stopPrintingB
- (void)stopPrintingB
{
    b = false;
}

#3


If you run your program in debug mode you can inject code that will break the loop. In the example posted just change:

如果在调试模式下运行程序,则可以注入会破坏循环的代码。在发布的示例中只需更改:

b = true;
while(b){}

to:

b = true;
while(b){b=false;}

Then save the file and the loop will be broken.

然后保存文件,循环将被破坏。