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.
然后保存文件,循环将被破坏。