kotlin coroutines - why does Thread.sleep not pause main thread from with launch? - kotlin-coroutines

I wanted to try and pause the main thread from within a courtine. a few question but first let me show you the code block im working with as a test:
class MainActivity : Activity(), CoroutineScope by MainScope() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
launch(Dispatchers.Main) {
val threadName = Thread.currentThread()
Log.v("mytag", "$threadName")
Log.v("mytag", "111 ")
Thread.sleep(5000)
Log.v("mytag", "222")
}
Thread.sleep(2500) //give coroutine some time to launch fully.
Log.v("mytag", "333")
}
}
which yields an output of:
V/mytag: 333
V/mytag: Thread[main,5,main]
V/mytag: 111
V/mytag: 222
since im printing out the current thread name is it not main ? i am getting "Thread[main,5,main]"
so assuming that i am on main thread then why is it when i run Thread.sleep(5000) that "333" is getting printed ? i am expecting that "333" will be last to print since i've frozen the main thread.

The dispatcher Dispatchers.Main schedules the coroutine to run as soon as main thread has been freed up.
It doesn't launch up immediately, and since your onCreate() is running on main thread as well, so the main isn't free once onCreate(), main thread looper will check for any scheduled coroutine and runs it if there were.
If you explicitly want to launch immediately as after calling the launch, and if you are the owner of the thread (in this case main) and you are the owner here because your function onCreate is running on main, you can use the Dispatchers.Main.immediate dispatcher there.
// immediate will launch immediately if current function is running on Dispatchers.Main which is true
launch(Dispatchers.Main.immediate) {
val threadName = Thread.currentThread()
Log.v("mytag", "$threadName")
Log.v("mytag", "111")
Thread.sleep(5000)
Log.v("mytag", "222")
}
Thread.sleep(2500)
Log.v("mytag", "333")
Output (Logs):
V/mytag: Thread[main,5,main]
V/mytag: 111
V/mytag: 222
V/mytag: 333

so assuming that i am on main thread
Yes, I believe you are on the main thread. Coroutine infrastructure may rename the thread temporarily so you get better diagnostics on the actual coroutine running on that thread.
then why is it when i run Thread.sleep(5000) that "333" is getting printed ? i am expecting that "333" will be last to print since i've frozen the main thread.
Your launch call creates a new coroutine and adds it to the tail of the main thread's event queue. Then it goes on to block the main thread for 2.5 seconds. After that the onCreate callback may finally complete, the GUI event loop may go on processing events from the event queue, and eventually reach the one added there by your launch call, which will then again block the GUI thread for 5 seconds.

Related

pykd can not start thread use threading in python script

when I use threading.Thread to create new thread.it can not start. The code like this
import threading
import time
import sys
def worker():
count = 1
while True:
if count >= 6:
break
time.sleep(1)
count += 1
print("thread name = {}, thread id = {}".format(threading.current_thread().name,threading.current_thread().ident))
t1 = threading.Thread(target=worker,name="t1")
t2 = threading.Thread(target=worker,name='t2')
t1.start()
t2.start()
t1.join()
t2.join()
When I run this code. The windbg will not report error 、not print any thing and never return
enter image description here
I will to create new thread to run something
Don't use 'threading' within windbg. Windbg has own multithreading model and loop of debug events. It is near impossible to run all this threads together without bugs.
In fact I dont't recomend to use 'threading' also in standalone python program with pykd module. All my scripts always use 'multiprocessing' module.

Pytest a function which invokes asyncio coroutines

I am trying to write a unit testcase using mock and pytest-asyncio. I have a normal function launching an asyncio coroutine using asyncio.run. [Using python3.7]
import asyncio
async def sample_async(arg2):
# do something
proc = await asyncio.create_subprocess_shell(arg2)
# some more asyncio calls
rc = proc.returncode
return rc
def launcher(arg1, arg2):
if arg1 == "no_asyncio":
# do something
print("No asyncio")
return 0
else:
return_code = asyncio.run(sample_async(arg2))
# do something
return return_code
I was able to write unittest for the asyncio function sample_async but not for launcher. Here is what I have tried:
class AsyncMock(MagicMock):
async def __call__(self, *args, **kwargs):
return super(AsyncMock, self).__call__(*args, **kwargs)
#patch("asyncio.create_subprocess_shell", new_callable=AsyncMock)
def test_launcher(async_shell):
arg1 = "async"
arg2 = "/bin/bash ls"
sample.launcher(arg1, arg2)
async_shell.assert_called_once()
When I try to run the pytest, I keep getting RuntimeError: There is no current event loop in thread 'MainThread'. I can't use #pytest.mark.asyncio for this test as the function launcher is not an asyncio coroutine. What am I doing wrong here?
See here about explicitly creating an event loop:
RuntimeError: There is no current event loop in thread in async + apscheduler
See the documentation for get_event_loop() in particular here:
https://docs.python.org/3/library/asyncio-eventloop.html
If there is no current event loop set in the current OS thread, the OS thread is main, and set_event_loop() has not yet been called, asyncio will create a new event loop and set it as the current one.
Likely, because your OS thread is not main, you need to do some manual init'ing of the loop. Make sure you have a clear mental picture of the event loop and what these functions do in its lifecycle, think of the loop as nothing more than an object with methods and other objects (tasks) it works on. As the docs say, the main OS thread does some "magic" for you that isn't really magic just "behind the scenes".

Asyncio task vs coroutine

Reading the asyncio documentation, I realize that I don't understand a very basic and fundamental aspect: the difference between awaiting a coroutine directly, and awaiting the same coroutine when it's wrapped inside a task.
In the documentation examples the two calls to the say_after coroutine are running sequentially when awaited without create_task, and concurrently when wrapped in create_task. So I understand that this is basically the difference, and that it is quite an important one.
However what confuses me is that in the example code I read everywhere (for instance showing how to use aiohttp), there are many places where a (user-defined) coroutine is awaited (usually in the middle of some other user-defined coroutine) without being wrapped in a task, and I'm wondering why that is the case. What are the criteria to determine when a coroutine should be wrapped in a task or not?
What are the criteria to determine when a coroutine should be wrapped in a task or not?
You should use a task when you want your coroutine to effectively run in the background. The code you've seen just awaits the coroutines directly because it needs them running in sequence. For example, consider an HTTP client sending a request and waiting for a response:
# these two don't make too much sense in parallel
await session.send_request(req)
resp = await session.read_response()
There are situations when you want operations to run in parallel. In that case asyncio.create_task is the appropriate tool, because it turns over the responsibility to execute the coroutine to the event loop. This allows you to start several coroutines and sit idly while they execute, typically waiting for some or all of them to finish:
dl1 = asyncio.create_task(session.get(url1))
dl2 = asyncio.create_task(session.get(url2))
# run them in parallel and wait for both to finish
resp1 = await dl1
resp2 = await dl2
# or, shorter:
resp1, resp2 = asyncio.gather(session.get(url1), session.get(url2))
As shown above, a task can be awaited as well. Just like awaiting a coroutine, that will block the current coroutine until the coroutine driven by the task has completed. In analogy to threads, awaiting a task is roughly equivalent to join()-ing a thread (except you get back the return value). Another example:
queue = asyncio.Queue()
# read output from process in an infinite loop and
# put it in a queue
async def process_output(cmd, queue, identifier):
proc = await asyncio.create_subprocess_shell(cmd)
while True:
line = await proc.readline()
await queue.put((identifier, line))
# create multiple workers that run in parallel and pour
# data from multiple sources into the same queue
asyncio.create_task(process_output("top -b", queue, "top")
asyncio.create_task(process_output("vmstat 1", queue, "vmstat")
while True:
identifier, output = await queue.get()
if identifier == 'top':
# ...
In summary, if you need the result of a coroutine in order to proceed, you should just await it without creating a task, i.e.:
# this is ok
resp = await session.read_response()
# unnecessary - it has the same effect, but it's
# less efficient
resp = await asyncio.create_task(session.read_reponse())
To continue with the threading analogy, creating a task just to await it immediately is like running t = Thread(target=foo); t.start(); t.join() instead of just foo() - inefficient and redundant.

SubscribeOn main thread

How can I set the async operator of Observable to run in the main thread instead in another thread. Or at least set to get the result in the main thread once we finish.
#Test
public void retryWhen() {
Scheduler scheduler = Schedulers.newThread();
Single.just("single")
.map(word -> null)
.map(Object::toString)
.retryWhen(ot ->
ot.doOnNext(t -> System.out.println("Retry mechanism:" + t))
.filter(t -> t instanceof NullPointerException && cont < 5)
.flatMap(t -> Observable.timer(100, TimeUnit.MILLISECONDS,scheduler))
.doOnNext(t -> cont++)
.switchIfEmpty(Observable.error(new NullPointerException())))
.subscribeOn(scheduler)
.subscribe(System.out::println, System.out::println);
// new TestSubscriber()
// .awaitTerminalEvent(1000, TimeUnit.MILLISECONDS);
}
I´m trying observerOn and subscribeOn but both are used to set in which thread you want the execution. But in my case I want the execution or the end of it in the same thread where I run the test
Right now the only way to see the prints are just blocking and waiting for the execution.
Regards.
You could use Observable.toBlocking() to get a BlockingObservable and use that to extract your results in your tests.
If you don't specify observeOn/subscribeOn and no operator or Observable changes the thread, then when you subscribe to the observable it will do all the processing during the subscription.

System does not sleep after restoring the default settings using SetThreadExecutionState

I created a method to prevent the system from sleeping as follows:
public static void KeepSystemAwake(bool bEnable)
{
if (bEnable)
{
EXECUTION_STATE state = SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
}
else
{
EXECUTION_STATE state = SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
}
}
The method prevents the system from sleep but when I call the ES_CONTINUOUS part of the method,the system does not sleep at all when I want it behave normally. What am I missing? I'm running this code in a different thread (Timer)
I'm running this code in a different thread (Timer)
If you're using something like a System.Threading.Timer callback, it will be called on different (read: arbitrary) threads.
From MSDN:
The callback method executed by the timer should be reentrant, because it is called on ThreadPool threads
Make sure you're calling SetThreadExecutionState for the same thread. Ideally, you'll serialise calls onto one thread (like the main thread).

Resources