I have a function(be it a static function or totally unaffiliated one) and a specific thread
class AnyClass{
static func foo(myThread: NSThread) {
....
// I want this *blablabla* to be performed on myThread
....
}
}
How can I make is happen?
Don't use thread, use dispatch queue (Grand Central Dispatch) instead. See Apple's documentation on Migrating away from threads.
A typical usage pattern for GCD is:
class AnyClass{
static func foo(queue: dispatch_queue_t) {
....
let group = dispatch_group_create();
dispatch_group_enter(group) // tell the OS your group has started
dispatch_group_async(group, queue) {
// Do your things on a different queue
....
dispatch_group_leave(group) // tell the OS your group has ended
}
// Do your other things on the original thread simultaneously
....
dispatch_group_wait(group, DISPATCH_TIME_FOREVER) // wait for the queue to finish
// Do other things still
....
}
}
// Calling the function
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
AnyClass.foo(queue)
Related
I'm developing an app for Windows in Visual C++ which would get inputs from a web API. Some of the API calls require me to request response in some specified time delay and during this time I would like to display a spinner.
I'm all good with the displaying spinner, disabling the buttons etc for the time I need to wait before proceeding to the request, but don't know how to pause the process within the app. Obviously, if I use the _sleep function, the app becomes unresposive.
Here's more or less what I need to achieve (pseudo-code)
void doSomething()
{
ui->button1->setEnable(false);
SendAPIReuqest1();
while (APIRequest1_success)
{
requestAPIRequest1_response();
//wait 10s if false and retry, this can take up to 5mins
}
SendAPIRequest2();
//wait 30s - here I know I can start the job on my end exactly after 30s
doSometing2();
ui->button1->setEnable(true);
}
What would be the correct approach to achieve what I need?
You'll most likely just want to poll for a response from the web API, alternatively you can start a secondary thread to check for a response from the web API;
After seeing some minimal code, something similar to this may work.
//takes an initial start time, calculates elapsed time, compares elapsed time to count
bool ready(std::chrono::time_point<std::chrono::system_clock>&start, const double& count) {
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> diff = end-start;
if (diff.count() >= count) {
start = end;
return true;
}
return false;
}
void doSomething()
{
static std::chrono::time_point<std::chrono::system_clock> start;
static int state = 0;
switch(state) {
case (0):
ui->button1->setEnable(false);
SendAPIRequest1();
if (APIRequest1_success) {
start = std::chrono::system_clock::now();
++state;
}
break;
case (1):
if (ready(start, 10.0) && requestAPIRequest1_response()) ++state;
break;
case(2):
SendAPIRequest2();
start = std::chrono::system_clock::now();
++state;
break;
case(3):
if (ready(start, 30.0)) {
doSomething2();
ui->button1->setEnable(true);
state = 0;
}
break;
}
}
This way you can call the function and it will either attempt one of the requests or return to do other tasks.
or with threads it could be as simple as
void worker_func(std::promise<bool>&& result) {
using namespace std::chrono_literals;
SendAPIRequest1();
while (!requestAPIRequest1_response()) {
std::this_thread::sleep_for(10s);
}
SendAPIRequest2();
std::this_thread::sleep_for(30s);
doSomething2();
result.set_value(true);
}
void doSomething() {
static std::future<bool> finished;
static bool flag = true;
if (flag) {
std::promise<bool> _finished;
finished = _finished.get_future();
ui.button1.setEnable(false);
std::thread worker(worker_func, std::move(_finished));
flag = false;
} else if (finished.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
//finished.get();
worker.join();
ui.button1.setEnable(true);
flag = true;
}
}
This way your main thread can keep running the ui, while the worker thread waits for the web API response, as long as your requests aren't handling any QT ui components I believe this should work.
Edit:
Since I have never used QT and it was never mentioned originally that QT was being used the above answers may or may not be usefull, however it looks like QT has some functions to handle things like this. maybe you can just start and stop a Qtimer
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &foo::update);
timer->start(1000);
would run the function foo::update() every second, the time interval can be changed accordingly. Here is a reference to QTimer and a reference to another class which may be of interest QTimerEvent not to mention, QT has an entire event handling system The Event System
I have following receiver construction based on time.Ticker, which calls method receive() every given constant time interval, controlled by channels (To fetch some useful data from server).
There is a main routine with main application logic and second routine with this receiver logic (defined in Start() method). And there is a following problem: when I'm trying to stop receiver routine from main routine (using defined Stop() method) while receive()waits for data from UDP connection, main routine seems to freeze (I have some GUI there and it doesn't allow to interract). I don't actually understand why is this happening, beacuse channels should allow me to interract with this receiver routine. I need to stop this receiver in given point of time even if it is still waiting for UDP data and main routine should still be able to work. I would be grateful for explaination and some idea how to approach stopping this receiver without freezing main routine.
Greetings
type RtpReceiver struct {
Ticker *time.Ticker
Interval time.Duration
doneCheck chan bool
started bool
// some othe fields
}
func NewRtpReceiver() *RtpReceiver {
// some logic
return &RtpReceiver{
doneCheck: make(chan bool),
started: false,
}
}
func (receiver *RtpReceiver) receive() {
_, _, _ = (*receiver.UdpCon).ReadFrom(receiver.buffer)
// some logic
}
func (receiver *RtpReceiver) Start() {
receiver.started = true
receiver.Ticker = time.NewTicker(receiver.Interval)
go func() {
for {
select {
case <-receiver.doneCheck:
return
case <-receiver.Ticker.C:
receiver.receive()
}
}
}()
}
func (receiver *RtpReceiver) Stop() {
if receiver.started {
receiver.doneCheck <- true
receiver.Ticker.Stop()
receiver.started = false
}
}
So looking at Coroutines for the first time, I want to process a load of data in parallel and wait for it to finish. I been looking around and seen RunBlocking and Await etc but not sure how to use it.
I so far have
val jobs = mutableListOf<Job>()
jobs += GlobalScope.launch { processPages(urls, collection) }
jobs += GlobalScope.launch { processPages(urls, collection2) }
jobs += GlobalScope.launch { processPages(urls, collection3) }
I then want to know/wait for these to finish
You don't need to manually keep track of your cuncurrent jobs if you use the concept of structured concurrency. Assuming that your processPages function performs some kind of blocking IO, you can encapsulate your code into the following suspending function, which executes your code in an IO dispatcher designed for this kind of work:
suspend fun processAllPages() = withContext(Dispatchers.IO) {
// withContext waits for all children coroutines
launch { processPages(urls, collection) }
launch { processPages(urls, collection2) }
launch { processPages(urls, collection3) }
}
Now, from if a topmost function of your application is not already a suspending function, then you can use runBlocking to call processAllPages:
runBlocking {
processAllPages()
}
You can use async builder function to process a load of data in parallel:
class Presenter {
private var job: Job = Job()
private var scope = CoroutineScope(Dispatchers.Main + job) // creating the scope to run the coroutine. It consists of Dispatchers.Main (coroutine will run in the Main context) and job to handle the cancellation of the coroutine.
fun runInParallel() {
scope.launch { // launch a coroutine
// runs in parallel
val deferredList = listOf(
scope.asyncIO { processPages(urls, collection) },
scope.asyncIO { processPages(urls, collection2) },
scope.asyncIO { processPages(urls, collection3) }
)
deferredList.awaitAll() // wait for all data to be processed without blocking the UI thread
// do some stuff after data has been processed, for example update UI
}
}
private fun processPages(...) {...}
fun cancel() {
job.cancel() // invoke it to cancel the job when you don't need it to execute. For example when UI changed and you don't need to process data
}
}
Extension function asyncIO:
fun <T> CoroutineScope.asyncIO(ioFun: () -> T) = async(Dispatchers.IO) { ioFun() } // CoroutineDispatcher - runs and schedules coroutines
GlobalScope.launch is not recommended to use unless you want the coroutine to be operating on the whole application lifetime and not cancelled prematurely.
Edit: as mentioned by Roman Elizarov you can try not to use awaitAll() function unless you want to update UI or do something else right away after all data are processed.
Following approach can be used.
fun myTask() {
GlobalScope.launch {
val task = listOf(
async {
},
async {
}
)
task.awaitAll()
}
}
It is easy enough in D to create a Queue type using the std.container.dlist.
I would like to have multiple threads but have them communicate with a queue, not with message passing (https://tour.dlang.org/tour/en/multithreading/message-passing). As I understand it the messages are designed to always receive data at particular points in the code; the receiving thread will block until the expected data is received.
(EDIT: I was informed about receiveTimeout but having a no timeout and just a check is really more appropriate in this case (maybe a timeout of 0?). Also I am not sure what the message API will do if multiple messages are sent before any any are received. I will have to play with that.)
void main() {
spawn(&worker, thisTid);
// This line will block until the expected message is received.
receive (
(string message) {
writeln("Received the message: ", text);
},
)
}
What I am needing is to merely receive data if there is some. Something like this:
void main() {
Queue!string queue// custom `Queue` type based on DList
spawn(&worker, queue);
while (true) {
// Go through any messages (while consuming `queue`)
for (string message; queue) {
writeln("Received a message: ", text);
}
// Do other stuff
}
}
I have tried using shared variables (https://tour.dlang.org/tour/en/multithreading/synchronization-sharing) but DMD is complaining that "Aliases to mutable thread-local data not allowed." or some other errors, depending.
How would this be done in D? Or, is there a way to use messages to do this kind of communication?
This doesn't answer the specific question but ti does clear up what I think is a misunderstanding of the message passing api...
just call receiveTimeout instead of plain receive
http://dpldocs.info/experimental-docs/std.concurrency.receiveTimeout.html
I use this:
shared class Queue(T) {
private T[] queue;
synchronized void opOpAssign(string op)(T object) if(op == "~") {
queue ~= object;
}
synchronized size_t length(){
return queue.length;
}
synchronized T pop(){
assert(queue.length, "Please check queue length, is 0");
auto first = queue[0];
queue = queue[1..$];
return first;
}
synchronized shared(T[]) consume(){
auto copy = queue;
queue = [];
return copy;
}
}
I have gotten the answer I need.
Simply put, use core.thread rather than std.concurrency. std.concurrency manages messages for you and does not allow you to manage it yourself. core.thread is what std.concurrency uses internally.
The longer answer, here is how I fully implemented it.
I have created a Queue type that is based on an Singly Linked List but maintains a pointer of the last element. The Queue also uses standard component inputRange and outputRange (or at least I think it does) per Walter Brights vision (https://www.youtube.com/watch?v=cQkBOCo8UrE).
The Queue is also built to allow one thread to write and another to read with very little mutexing internally so it should be fast.
The Queue I shared here https://pastebin.com/ddyPpLrp
A simple implementation to have a second thread read input:
Queue!string inputQueue = new Queue!string;
ThreadInput threadInput = new ThreadInput(inputQueue);
threadInput.start;
while (true) {
foreach (string value; inputQueue) {
writeln(value);
}
}
ThreadInput being defined as thus:
class ThreadInput : Thread {
private Queue!string queue;
this(Queue!string queue) {
super(&run);
this.queue = queue;
}
private void run() {
while (true) {
queue.put(readln);
}
}
}
The code https://pastebin.com/w5jwRVrL
The Queue again https://pastebin.com/ddyPpLrp
Here i attached my example that i used for performance test. Why there is so much diffrence between all this ? (This is sample console application)
class Program
{
internal class ThreadObj
{
public ManualResetEvent signalComplete { get; set; }
public int TaskItem { get; set; }
}
static void ThreadWork(object o)
{
ThreadObj obj = (ThreadObj)o;
System.Threading.Thread.Sleep(5000);
obj.signalComplete.Set();
}
static void Main(string[] args)
{
// Using new .net 4.0 Task
Stopwatch watch = new Stopwatch();
watch.Start();
System.Collections.Concurrent.ConcurrentBag<Task> tasks = new System.Collections.Concurrent.ConcurrentBag<Task>();
Parallel.For(0, 60, i =>
{
Task t = Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(5000);
}, TaskCreationOptions.PreferFairness);
tasks.Add(t);
});
Console.WriteLine("Waiting for task to finish");
Task.WaitAll(tasks.ToArray());
watch.Stop();
Console.WriteLine("Complete(Tasks) : Time " + watch.ElapsedMilliseconds.ToString());
// Using Thread
watch.Reset();
watch.Start();
System.Collections.Concurrent.ConcurrentBag<ManualResetEvent> tasksThreads = new System.Collections.Concurrent.ConcurrentBag<ManualResetEvent>();
Parallel.For(0, 60, i =>
{
ManualResetEvent signal = new ManualResetEvent(false);
tasksThreads.Add(signal);
Thread t = new Thread(new ParameterizedThreadStart(ThreadWork));
t.Start(new ThreadObj() { signalComplete = signal, TaskItem = i });
});
Console.WriteLine("Waiting for task to finish");
WaitHandle.WaitAll(tasksThreads.ToArray());
watch.Stop();
Console.WriteLine("Complete(Threads) : Time " + watch.ElapsedMilliseconds.ToString());
// Using ThreadPool
watch.Reset();
watch.Start();
System.Collections.Concurrent.ConcurrentBag<ManualResetEvent> tasksThreadPools = new System.Collections.Concurrent.ConcurrentBag<ManualResetEvent>();
Parallel.For(0, 60, i =>
{
ManualResetEvent signal = new ManualResetEvent(false);
tasksThreadPools.Add(signal);
ThreadObj obj = new ThreadObj() { signalComplete = signal, TaskItem = i };
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadWork), obj);
});
Console.WriteLine("Waiting for task to finish");
WaitHandle.WaitAll(tasksThreadPools.ToArray());
watch.Stop();
Console.WriteLine("Complete(ThreadPool) : Time " + watch.ElapsedMilliseconds.ToString());
Console.ReadLine();
}
}
Please provide your suggetion on this.
Here is sample output that i got.
Waiting for task to finish
Complete(Tasks) : Time 28050
Waiting for task to finish
Complete(Threads) : Time 5435
Waiting for task to finish
Complete(ThreadPool) : Time 15032
You're test case is far from solid to begin with. When you perform actual computation work within the threadWork method, you'll find that the results are very different. TPL uses the threadpool internally so it's a matter of Threadpool vs Threads. The reason for the TPL to be so different compared to the Threadpool is likely in the nature of the Threadpool itself (will come back on that one later).
Look at the time it took for Threads to complete. Your test method only sleeps for 5 seconds, that's it. Now where did the other .43 second go to? Right, to the creation and destruction of the Thread itself and the associated overhead including context switching. The Threadpool has a queue of Threads that can be used to execute simultaneously. It's up to the Threadpool and it's configuration to create and destroy extra threads whenever it deems needed. When you schedule 60 items in the Threadpool , the Threadpool wont likely create 60 threads to handle all items simultaneously but rather use a sub amount of that and handle multiple items per thread. Since your test method is only sleeping, this explains the big difference between the time spent with threads and the time spent with the Threadpool.
Since TPL uses the Threadpool internally and before you're ThreadPool test ran, it is logical to assume that, at that stage: less threads were available in the Threadpool, but due to the run of the TPL, more threads were created for the Threadpool so in turn, when your Threadpool test ran, there were more threads available initially which explains the difference between TPL and the Threadpool.
Practically, you want to use the Threadpool as much as possible, especially for computational operations. When you need to synchronize with an external resource like downloading something from the web, i recommend not using a thread but one of the more advanced async options available in .NET for getting that particular resource.