Android Python Multiple Threads - android

Hello I am having issues in regards to running threads in Android with Python SL4A. I am trying to run two threads at the same time, but seem to be having issues
from threading import *
import time
def func1():
while True:
print("func1")
def func2():
while True:
print("func2")
thread = Thread(target = func1)
thread.start()
for i in range(1000):
thread = Thread(target = func2)
thread.start()
time.sleep(2)
time.sleep(2)
the first thread func1 starts fine but then is never run again once func2 takes over.
Would anyone have any advice on how to fix this?
Thank you

I'm not sure what you're expecting here. You first pass func1 into a thread, then start it. You never reference func1 or the thread again after that.
Later, you create an iterator, within which you pass func2 into a new thread and start it. You repeat that process a thousand times, with a two second sleep between each.
Do you want both functions to run a thousand times? If so...
thread1 = Thread(target=func1)
thread2 = Thread(target=func2)
for i in range(1000):
thread1.start()
thread2.start()
time.sleep(2)
Note that in your code the variable thread is assigned Thread(target=func1) before the iterator. Inside the iterator, the same name, thread, is assigned Thread(target=func2), so it no longer points to the same thing.
Also, if you're creating an object to reference it in a loop, you want to try and keep the initialisation outside of the loop, so you don't create the same object over and over. Just create one, then reference it in the loop.

Related

Activity not updating in tight loop

I have a situation where I want to update an Activity's text fields as data comes in. The update only occurs when the simulation is completed, not while it is running (takes maybe 2 seconds to run).
Here is the code I have:
...
private var totalLoops = 0
private val updateDisplayTask = Runnable {
totalLoopsTV.text = totalLoops.toString()
totalEmailsSentTV.text = totalEmailsSent.toString()
totalPushesSentTV.text = totalPushesSent.toString()
private fun mainLoopFunction(currentTime: Long) {
...
totalLoops++
if(totalLoops % 20 == 0 || onDeckList.size == 0) {
Timber.w("UPDATING UI")
runOnUiThread(updateDisplayTask)
//handler.post(updateDisplayTask)
}
} //end of main loop
I've tried both runOnUiThread and handler/post as well as a few other things using Kotlin Coroutines, but nothing so far has worked. Can you see what I'm doing wrong here please? I see the logs of UPDATING UI so I know that the updates do get sent and I do see the last update (the only one I see) at the end.
Is this running on another thread, and then you run updateDisplayTask on the main thread? If you're updating totalLoops, totalEmailsSent and totalPushesSent on one thread (this worker thread) and reading them on another (main thread) then because of the way concurrency works, you might not actually see the new values on the main thread.
There are a few ways to manage synchronizing them, but if you're only writing the values on one thread (and you're not massively concerned about the possibility of some of the values changing partway through reading them, so they don't all match up) you can just use the #Volatile annotation on those variables to make them update across threads (works like the volatile keyword in Java).
If you care about atomic updates (everything changing together, can't read or write while something is in the middle of reading or writing them) you'll have to look into some kind of locking, like using synchronized methods and blocks. It's kind of a major (important!) subject, here's a post on it:
https://proandroiddev.com/synchronization-and-thread-safety-techniques-in-java-and-kotlin-f63506370e6d

Xamarin Android correct Asynchronous way

i am new on xamarin android apps.I want to build an app and i have read that connections with database or the execution of queries should happen asynchronously from the main thread otherwise the UIthread will may collapse.I have found 2 ways to do that:
First way:
WebClient client = new WebClient();
Uri uri = new Uri("http://192.168.2.8/CreateUsername.php");
NameValueCollection parameters = new NameValueCollection();
parameters.Add("Name", txtname.text);
client.UploadValuesCompleted += Client_UploadValuesCompleted;
client.UploadValuesAsync(uri,parameters); ---> is this gonna create a new thread and run asynchronously???
(here i found the first way: https://www.youtube.com/watch?v=jF3D__ibrx8 )
SecondWay:
https://developer.xamarin.com/recipes/android/web_services/consuming_services/call_a_rest_web_service/
Both ways are correct?both of ways are gonna create a new thread and run asynchronously?Thanks!!!!
Both examples are ok but I'd usually trust the official documentation by Xamarin first. What might confuse you with the first example is the lack of await keyword when calling the UploadValuesAsync method. Here's what actually happens:
Call to UploadValuesAsync is made from the UI thread.
UI thread blocks until the method returns because it's running synchronously.
However, the method returns very quickly because it launches the upload process asynchronously on another thread internally and doesn't wait for the process to complete.
When the whole upload process is finished, Client_UploadValuesCompleted will be called.
As you can see on the WebClient.UploadValuesAsync page on MSDN, it states that:
These methods do not block the calling thread.
Also, when looking at the source code for UploadValuesAsync, you'll notice the following attribute defined on top:
[HostProtection(ExternalThreading=true)]
which means the following:
Code that exposes external threading creates or manipulates threads other than its own, which might be harmful to the host.
To sum it up, the upload process is handled on another background thread but otherwise, your code will run synchronously. There's a bit more asynchronicity going on in Xamarin's sample.

Android: Process.myTid() VS Thread.currentThread().getId()

I have simple Activity that calls AsyncTask, so I print some id's regarding Proces and Thread:
From onCreate android.os.Process.myUid(): 10137
From onCreate android.os.Process.myPid(): 29776
From onCreate android.os.Process.myTid(): 29776
From onCreate Thread.currentThread().getId(): 1
/****************************************************************/
From Async doInBackground android.os.Process.myUid(): 10137
From Async doInBackground android.os.Process.myPid(): 29776
From Async doInBackground android.os.Process.myTid(): 30426
From Async doInBackground Thread.currentThread().getId(): 12556
Uid is same because its app-specific sandbox
Similar with Pid: Each app is one Process
3rd line in onCreate same as Pid because it's the UIThread and in Android OS as based on Linux we know that issue regarding Process is actually Thread etc... And in the Async the ThreadId is different because AsyncTask runs on different Thread rather then the UIThread
The thing I'm struggling to understand is Thread.currentThread().getId(). What I expect is to get same id as Thread.currentThread().getId() for the same execution environment. e.g. for onCreate I want lines 3,4 to be same (29776), and for Async I expect lines 3,4 to be the same (30426). What is going on here?
Thanks,
Very interesting question by the OP and I decided to dig (love open source).
The short answer is: they're different because they're different, because they were never meant to be the same.
Process.myTid() is the linux thread ID
Thread.getId() is a simple sequential long number.
But the short answer is boring, so let's explore where the answer comes from (links in the answer points to the relevant source codes).
In Process.myTid(), you'll see that is simply calls from Os.gettid() that in itself calls a native method on Libcore for that method is below:
public static int gettid() { return Libcore.os.gettid(); }
furthermore the docs for Os.gettid(); you'll find a link to Linux Programmer's Manual
gettid() returns the caller's thread ID (TID). In a single-threaded
process, the thread ID is equal to the process ID (PID, as returned
by getpid(2)). In a multithreaded process, all threads have the same
PID, but each one has a unique TID.
That means, Process.myTid() returns the thread ID as given by the Linux kernel.
On the other hand Thread.getId() is simply returning a long. This long is assigned during init(...) as tid = nextThreadId();. Then the last piece of this puzzle, below is the code for nextThreadId()
/* For generating thread ID */
private static long threadSeqNumber;
private static synchronized long More ...nextThreadID() {
return ++threadSeqNumber;
}
That means, Thread.getId() is simply a "java layer" static long being auto-increment for each thread.

3 thread running at high frequency uses the same variables

I'm developing an android application that at high frequency receives data from ble notify, print data on the screen and send data to other peripherall.
This is my situation :
onCharacteristicChanged callback receives a byte array called
"value" at 10hz and unpacks data in some float and int variables
an Handler associated with an handlerThread starts a Runnable
every 30hz. This runnable use the variables unpacked from value,
saves the new data in some variables and sendbroadcastmessage to the
UX
another thread every 10hz use the data saved in
step 1 and 2 does some math operation on this variables and write
data on the characteristic.
In the step above I save and use float, double and int variables.
I'm afraid to handles the concurrency and I'm thinking to resolve the concurrency problems using the same handlerthread in the step 2 and 3. But when the other notify arrives I think that there is a race condiction problem :/
other question : oncharacteristicchanged in what thread is executed ?
more information of my problem :
in oncharacteristicchanged arrives new byte array (at 10hz frequency), I unpack data in variables , in other thread B (at 30hz) use this data do some calculation: sendbroadcast to the ux and save the result in some other variables; the thread C use the result of the thread B, it does some other calculation and write on characteristic at 10hz.
oncharacteristicchanged -> Thread B -> Thread C
But I can't stop oncharacteristicchanged because I don't know in what thread it is executed..
Do you
I don't understand Android, but I do Java. I'll try to help you even not knowing Android, so let's go!
"In the step above I save and use float, double and int variables."
First of all, I'd start using thread safe variables, such as: AtomicInteger or declare them as volatile.
For all your methods that will be accessed by multi-threading, I'd say to make them thread safe. I don't know if in Android there is the class Lock or the keyword synchronized, but I'd start from there.
Example:
Lock lock = new ReentrantLock();
try {
lock.lock();
doYourWork();
} finally{
lock.unlock();
}
Thats the way to start... Hope I helped you a little bit even not knowing Android and sorry if I said anything wrong.

Android , thread usage

My program is sending data to web server when accelerometer datas exceed the threshold which determined by me. So , I used thread mechanism for sending operation :
if( threshold is exceeded )
thread_send .start();
But this usage cause "Thread Already Used" error. So I used a method that I think is bad is below and it works :
if( threshold is exceeded ) {
thread_send = new Thread(this);
send_thread.start();
}
New thread is created at every turn. Does that usage cause negative results? (For example, memory problem or performance problem etc.)
What are your suggestions?
Editted :
My program should send data to web server very often. The most important thing is working correctly.So slow working is allowable , as long as the program can't stop suddenly..
I used ExecutorService in line with your suggestions :
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
........
if( threshold is exceeded ) {
threadExecutor.execute(this);
}
But errors occured : RecejtedExecutionException..
What can I do ?
The second code looks correct, though it may slow it down if too many threads are running in parallel. Depending on the application, it might be appropriate to have threads run one-at-a-time in a queue, using Executors.newSingleThreadExecutor.
One idea is creating a singleton like service that runs the thread, that way if one isn't running, then it starts one, otherwise it ignores it.
If you want multiple running at the same time, what you have is correct. Remember a thread can only be ran once per new Thread()

Categories

Resources