I read the "IOS Developer Library" about the "Run Loops" theme, in the article, one sentence says "It is possible to run a run loop recursively". My question is in which scenario should use the recursive run loop please?
My another question is about the statement "The purpose of a run loop is to keep your thread busy when there is work to do and put your thread to sleep when there is none.". How can a run loop sleep, can the main thread's run loop sleep when no event comes? What about the second thread's situation?
one example of the nested run loop that I found from Internet is that like
below:
[NSThread detachNewThreadSelector:#selector(runOnNewThread) toTarget:self withObject:nil];
while (!end) {
NSLog(#”runloop…”);
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
NSLog(#”runloop end.”);
}
The current thread will be blocked until the work in another thread has finished. But why this happen, how the current thread can be blocked?
Can anyone answer my question?
maybe an analogy is, pretend a run loop is an infinite while loop (which it basically is), then if you made another infinite while loop inside that one, the outer while loop would never loop again because the inner one is infinite, so what they have done is made it so when you make an inifinite while loop in another, it instead goes out of the outer one, and runs along beside it (on another thread)
in response to your update:
surely it will be blocked for no other reason than the while loop doesnt have an end condition
while (!end) {
if end is controlled from another thread, then that thread would have to set end to true before the current thread can move on from this while loop.
this code just seems really bad, it keep restarting the current runloop, probably defeating it purpose
Related
This is my code
https://pastebin.com/fnZreFKA
I have tried all the coroutine options, I have print statements at the start of each of the two functions, it prints, but it doesn't do anything in the loop
coroutine.wrap(constantWork)()
coroutine.wrap(lookForKeys)()
The loops start after line 170
Because they are not detached threads, they are green synchronous threads, only one of them will run the code at the time.
To simulate multitasking you forgot to use yield. coroutine.yield pauses the thread and runs the next code after you called the coroutine. You can resume the coroutine later on by calling wrapped coroutine again or using coroutine.resume if you created it using coroutine.create.
Read the documentation here: https://www.lua.org/pil/9.html
coroutine.wrap creates a new coroutine based on the function you passed it, and then creates a new function based on the coroutine. The first time you call it, it calls the original function until it yields. The next time, it returns from the yield and runs until the next yield. And so on.
In ComputerCraft, yielding is the same as waiting for an event.
ComputerCraft comes with the parallel library which runs two or more functions as coroutines in parallel. It does all the work for you.
You can use parallel.waitForAll or parallel.waitForAny, depending on when you want it to return.
Usage: parallel.waitForAll(constantWork, lookForKeys)
I am trying to have a while loop in my on_input that will continuually execute piece of code every few seconds
while(action_id == hash("click"))
do
print("Going")
end
I have tried moving it into other functions that are called by on_input, but every time a run this piece of code it crashes the program.
EDIT: I found that I was supposed to make sure the condition becomes false, stupid mistake.
The on_input() function is called by the engine every frame that some kind of input is received. What you are doing is entering an infinite loop during the frame when you receive an action_id that is "click". The loop will never complete since action_id will not change and the engine will lock up.
I just needed to make sure the conditional is false. I initially thought that the while loop would simply execute and then execute, this should have been done by an if statement.
I use the excellent OmniThreadLibrary library to implement threaded source code parsing, the program need to abandon the existing parsing and restart the parsing whenever the source code is changed.
I do this with the code snippet shown below, is it the correct way? Do I still have to check the Terminated property of the thread in the ThreadedParseHtml function?
if FParserThread <> nil then
begin
FParserThread.RemoveMonitor;
FParserThread.Terminate(500);
end;
FParserThread := CreateTask(ThreadedParse);
FParserThread.SetParameter('SourceCode', Editor.Lines.Text);
FParserThread.MonitorWith(FParserThreadMonitor);
FParserThread.Run;
Thanks in advance!
Edit 1: Sorry for reopening this question, but I found memory leaks when FParserThread is not completed by itself by calling the Terminate method with enough time given... Any ideas as to what might cause the memory leaks? Thanks!
Edit 2: Read this blog post, I still couldn't figure what the problem might be, since after every steps in ThreadedParse the code break if Terminated is ture...
Edit 3: Answering Rob's questions:
In the OnTerminated event handler (not shown here), FParserThread is set to "nil", so by "FParser is completed by itself", I mean the if FParserThread <> nil then block is not executed, in that case FParserThread is terminated because it's parsing has been completed.
The logic behind the code is that, this is a code editor, upon any code edits there will be a thread being started to parse the source code into the internal tree presentation, in the case when a new code edit happens but the previous parsing thrad hasn't been edited, the program will first forcibly the previous parsing thread then start a new one. This maybe is not a good approach...
Edit 4: After reading this similar SO question, I changed my code to call FParserThread.Terminate without a parameter which means, if I understand it correctly, that statement will only signal the thread to end, and inside the actual thread task, I applied the logic to exit the thread execution if the Terminated property is True.
Now what's wired is that, with the help of Tracetool, I found that after calling FParserThread.Terminate the OnTaskMessage event (where I clean up the memories) would not be fired again, that's what caused the memory leaks....
You don't have to check the Terminated property in the associated task. You're calling Terminate(1), which will forcefully kill the thread if it doesn't end itself within the 1 ms window that you've specified.
However, it's really not a good idea to forcefully kill a thread. That thread might have possessed a mutex or critical section when you killed it, so killing it will leave shared data in an inconsistent state. That could have a detrimental effect on your entire program.
Better is to notify your thread that you want it to terminate, but give it a more realistic deadline for termination. Within the other thread, you should occasionally check whether the thread has been asked to terminate, and then have it terminate itself gracefully.
If the thread doesn't end within the specified time limit, then you have bigger problems, and forcefully killing it won't solve them.
OP here, after using OmniThreadLibrary for over 2 years now, my conclusion is that the proper way of stopping a OTL task is using the cancellation tokens. Code Example below.
In the caller thread (usually the main thread), call:
//this will tell (not kill) the thread identified by myTask to stop.
myTask.CancellationToken.Signal;
In the callee thread you must regularly check the task.CancellationToken.IsSignaled property, if it becomes true, exit the execution and the thread termination will be handled by the system and OTL:
if task.CancellationToken.IsSignaled then
Exit;
I'm trying to do something a little fancy here, but the docs suggest it should be possible. Maybe LLDB is still too new, but I'm getting a lot of debugger crashes / deadlocks and even when that doesn't happen it does't seem to work like I expected.
I'm trying to put together a debug wrapper around all selector calls, to extract the message call graph inside a certain chunk of code. (I could explain why if you really want to know, but it isn't really relevant to the debugger issue.)
I start out with an Xcode breakpoint on the line where I want to start tracking things (for bonus points, this is happening on a secondary thread, but before you ask, no, nothing on any other thread is doing any accesses to this object or anything in its property subgraph):
[myObject startProcessing];
The breakpoint triggers, and I run "bt", just to extract:
* thread #5: tid = 0x2203, 0x000277d2 .........
I then do something mildly evil: I put a breakpoint in objc_msgSend, right at the instruction where it calls out to the real object selector. objc_msgSend looks like:
libobjc.A.dylib`objc_msgSend:
...(instructions)...
0x37babfa4: bx r12
...(more instructions)...
(Actually there are two bx calls but let's keep things simple.) I run:
breakpoint set -a 0x37babfa4 -t 0x2203
(TID included because I'm having enough trouble tracking this one thread and I don't need irrelevant stuff interfering.)
Here's where the scripting comes in. The setup described above works exactly as I'd like it to. If I resume execution until the breakpoint triggers, I can run:
frame select 0
thread step-inst -m this-thread 5
frame info
continue
and the effect will be that the debugger:
moves to the objc_msgSend frame
steps by one instruction, advancing it into the object selector frame it was pointing at
displays relevant details (object type, selector called)
resumes execution
at which point I can keep pasting in those four commands over and over and copying the output until I hate myself.
If, on the other hand, I run:
breakpoint command add -s command
and paste in those exact same commands, everything breaks. It does not advance to the object selector frame. It doesn't show the frame details, or at least not the correct ones -- depending on various tweaks (see below), it may or may not show "objc_msgSend" as being the current function. It doesn't resume execution.
In this case, if I could get that example working, I'd be mostly happy. But for even more bonus points, I've also tried this with python, which I would prefer because it would allow for much more sophisticated logging:
breakpoint command add -s python
> thread = frame.GetThread()
> thread.StepInstruction(1)
> newFrame = thread.GetFrameAtIndex(0)
> print " " * thread.GetNumFrames() + newFrame.GetFunctionName()
> process = thread.GetProcess()
> process.Continue()
> DONE
Again no good. Again depending on tiny details, this may or may not print something (usually objc_msgSend), but it never prints the correct thing. It never steps the instruction forward. It never resumes execution afterwards.
And again, the python version works fine if I do it by hand: if I wait till the breakpoint fires, then run "script" and enter those exact same lines, it works as expected. Some parts will even work in isolation, e.g. if I remove everything except the parts that get the process and call process.Continue() and trigger those automatically, that "works" (meaning I see the lldb prompt flashing rapidly as it suspends and resumes execution. Usually I regret this because it becomes unresponsive and crashes shortly after.)
So: Any ideas? Is the technology Not Ready Yet, or am I just missing some clever piece of the puzzle that will fix everything? Or should I give up entirely and just live with the fact that there are some parts of object internals that I will never understand?...
Breakpoint commands cannot resume execution and then get control back again, at least today. There are a lot of unresolved questions about what would happen if breakpoint 1 is running the process and then breakpoint 2 is hit. Besides the whole question of whether the code base can really handle nested breakpoints correctly (it was designed to...), what does it mean if breakpoint 2 decides execution should stop? Is breakpoint 1's state thrown away?
It seems a little esoteric to worry about a breakpoint hitting another breakpoint while stepping the inferior process but unless all the details have been worked out, it's easy for the user to shoot themselves in the foot. So for today, breakpoint commands can either stop when the breakpoint is hit or continue to run - but there isn't any ability to run a little bit and do more processing. I know this would be a really useful capability for certain tasks but there are a lot of gotchas that need to be thought out before it could be done.
For some cases, it is possible to handle it the other way around ... if you want to stop in function parser() only when it has been called by function lexer(), it is easy to put a breakpoint on lexer() with some a few python commands to go one stack frame up the stack and see what the calling function is. If it's not lexer(), continue. I don't think this will apply to what you're trying to do, though.
I am trying to create a sleep function for Lua, since my Lua-Scripts all run in a different thread/environment I wanted to yield their thread and restart from the main thread when the given amount of time elapsed, the main thread is in Java and the time elapsing is done with a loop.
Now this isn't really hard or something but I am trying to use Lua's own coroutines/threads so I don't have to create my own thread structure but (my Lua knowledge isn't top-notch) I don't know how I can yield a thread from outside of the thread.
Is it possible to yield a thread from the main thread?
Edit Nevermind, I just figured it out. I did a getfenv and used the coroutine.yield of the script it's own environment.
I used the script it's coroutine.yield function. Pretty easy looking back at it