How to wait for an event or timeout - objective-c

I'm trying a simple thread program.
I need to wait for a event and time delay. This time delay is varying. How to do this?
Can anyone explain with a sample program? I know how to spawn a thread with NSThreads as well as through NSInvocationOperation.

If you need to wait for a timeout consider using NSTimer. You can use setFireDate method to modify time delay.
For asynchronous events there's a lot of way to solve the problem, according to what you need in your program: first of all you may simply setting a delegate that receive a message when something happen in your class. If you need something more complex (in order to avoid race conditions or deadlocks) you may consider use NSNotificationCenter or NSConnection.

Related

Detect when block is added to Grand Central Dispatch?

I have an iOS application using NSThreads for concurrency tasks. I will try to migrate it to be using the Grand Central Dispatch (GCD) for handling concurrency.
The problem is that the app needs information regarding how many threads has been created since a given time. And how many threads that was spawned since that given time is currently running.
At the moment this is done by creating a category that does a method swizzling on the -main method in NSThread. In the new swizzled method it simply increments the total number of threads running and then decrement the same variable before the new swizzled -main method returns.
The problem is that when I use GCD dispatch_async it does not create a NSThread, hence my category approach does not work. How can I achieve the same while using GCD to handle concurrency?
What I would like to detect is when a new block is added to GCD, and when that block has been executed.
Any suggestions on how to achieve the same is very welcome.
EDIT
Many thanks to #ipmcc and #RyanR for helping me out on this. :) I believe I need to tell some more about the background and what I am trying to accomplish.
What I am actually trying is to extend the iOS testing framework Frank. Frank embeds a small web-server within a given app which enables sending HTTP request to the iOS application and thereby simulating events, a swipe or a tap gesture as an example.
I would like to extend it in a way that enables it to wait until all work triggered by a specific simulated event has ended before returning upon a request.
However I found it hard to detect exactly what work was triggered by the received event. And thats how I came to the solution to just reset a thread counter and then increment this counter for all created threads after the event was simulated, and decrement it when the threads are finishing. And then block until threads count became zero again. I know this approach is not perfect either, and it wont work with GCP.
Is there any other way to achieve it? Another possible solution which I have thought of is to specify that everything must run synchronized except the thread handling the HTTP request. However I don't know if this possible.
Any suggestions on how to achieve blocking after each simulated event until work triggered by that event has completed?
The problem is that the app needs information regarding how many
threads has been created since a given time. And how many threads that
was spawned since that given time is currently running.
You will not be able to get this information from GCD. One of the points of GCD is that you do not manage the thread pool. It is opaque. You'll note that even pthreads, the underlying threading library on which NSThread and GCD are built, does not have a (public) means to enumerate all existing threads or get the number of running threads. This is not going to be doable without hard core low level hackery. If you need to control or know the number of threads, then you need to be the one to spawn and manage them, and GCD is the wrong abstraction for you.
At the moment this is done by creating a category that does a method
swizzling on the -main method in NSThread. In the new swizzled method
it simply increments the total number of threads running and then
decrement the same variable before the new swizzled -main method
returns.
Note that this only tells you the number of threads started using NSThread. As mentioned, NSThread is a fairly high level abstraction on top of pthreads. There is nothing to prevent library code from spawning its own threads using the pthreads API that will be invisible to your count.
The problem is that when I use GCD dispatch_async it does not create a
NSThread, hence my category approach does not work. How can I achieve
the same while using GCD to handle concurrency?
In short, you can't. If you want to go forth and patch functions all over the various frameworks, then you should look up a library called mach_override. (But please don't.)
What I would like to detect is when a new block is added to GCD, and
when that block has been executed.
Since GCD uses thread pools, the act of adding a block does not imply a new thread. (And that's sorta the whole point.)
If you have some limited resource whose consumption you need to manage, the traditional way to do that would be with a limiting semaphore, but that is just one option.
This whole question just reeks of a poor design. Like the number of pthreads, GCD's queue widths are opaque/non-public. Your previous solution was not particularly viable (as discussed), and further efforts are likely to yield similarly poor solutions. You should really rethink your architecture such that knowing how many threads are running isn't important.
EDIT: Thanks for the clarification. There's not really a generic way, from the outside, to tell when all the "work" is done. What if an action sets up a timer that won't call back for ten minutes? At the extreme, consider this: the main runloop continues to spin for the entire life of the app, and as long as the main runloop is spinning, "work" could be being done on it.
In order to detect "doneness" your app has to signal doneness. In order to signal doneness, the app has to have some way (internal to itself) to know it's done. Put differently, the app can't tell something else (i.e. Frank) something it doesn't know. One way to go about this would be to encapsulate all the work you do in your app in NSOperations. NSOperation/NSOperationQueue provide good ways of reporting "doneness." At the simplest level, you could wrap the code where you kickoff work in an NSBlockOperation, then add a completion block to that operation that signals something else when it's done, and enqueue it to an NSOperationQueue for execution. (You could also do this with dispatch_group and dispatch_group_notify if you prefer working in the GCD style.)
If you have specific questions about how to package up your app's work into NSOperations, I would suggest starting a new question.
You can hook into the dispatch introspection functions (introspection.h, methods all start with dispatch_introspection), but you have to link with that library which is supposed to be only for debugging. I don't think you can include that in a release build. Your best bet would be to encapsulate GCD into your own object, so all your code submits blocks to execute through that object and it submits them to GCD after tracking whatever you're interested in. You won't be able to track thread consumption though, because GCD intentionally abstracts that and reuses threads.

Wait until dispatch_async thread ends

I am newcomer in Objective C.
I have an object, that creates new thread via GCD with dispatch_async in default queue.
I use dispatch_semaphore_wait with timeout = 1sec in thread to check when I need to close this thread.
When i call "close" method, it send dispatch_semaphore_signal and thread closes. But sometimes thread lives some time after "close" method ended. How could I wait in my "close" method until thread ends?
Thx.
Canonical answer to such a question: What are you trying to do?
I ask this because, first, you should neither need to know or care that there is a thread backing a GCD request and when it exits - that's entirely up to GCD to manage.
Second, you should always be suspicious of code that uses explicit timeouts (other than "FOREVER"). If you have any reason to ask yourself "Why 1 second? What happens if whatever event I'm waiting for takes more or less time than this?" then you are engaging in the kind of thinking that leads to polling, and polling is just BAD BAD (evil, wrong) design for pretty much everything but writing certain kinds of device drivers!
A far more reasonable approach is to use a completion callback at the end of your operation to signal that it's done, taking a fully async approach to programming and also following, in the process, one of the fundamental design principles of GCD.
It sounds to me, and I'm just guessing here, that you're taking an existing programming paradigm or way of thinking and erroneously applying it to GCD. An understandable mistake, but a mistake nonetheless.

What can I do if two detached threads overlap each other? queue

I'm not very 'up' on multi-threading, but I've been using detachNewThreadSelector in a couple of places to access data in a database. Unfortunately, on slower devices the first request may still be happening when I call the second... Which naturally causes a crash because both are calling the same method (which is obviously not thread-safe).
What is the best way to go about sorting a bug like this? Can I somehow queue them so that the second thread doesn't start until the first one has finished?
Thanks!
You may want to have a look at NSOperation and NSOperationQueue which is an abstraction for a queue of tasks that can be run asynchronously from the main thread. If you want the NSOperationQueue to run just a NSOperation at a time (so to wait after the current task is compleate before firing the next one) you can just set the maxConcurrentOperationCount property of the queue to 1
To extend ranos answer a bit, be sure to add operations from the same thread because if you add several NSOperations from several threads, they will run concurrently, even though maxConcurrentOperationCount on NSOperationQueue is set to 1.

Objective-C class time delay?

I was wondering if anyone knows of a class in objective-C that stops/delays the application at a specified amount of time during runtime? I've already looked at the Time Manager and NSTimer and don't see how I could possibly put a delay in there. I've never used these two classes before though, so maybe someone else has and could give me a tip? Thanks!
It really depends what you mean by "stops/delays the app." If you have a single threaded app you can just use anyone of the various sleep calls (usleep, sleep, nanosleep, etc). That is probably not what you want though, because it will just result in a hung UI for the user, and won't stop any background threads.
To actually give a decent answer it is probably necessary to know what you are actually trying to do. Are you waiting for something, polling a resource, etc?
#include <unistd.h>
sleep(3); // or usleep(3000000);
I think you're looking for [NSThread sleepForTimeInterval:] That should do the trick. You should also consider using a timer to invoke another function after a delay, because that solution is non-blocking. The NSThread approach will totally lock your application for the time interval if you call it from the main thread.

Objective C: How to kill a thread while in another thread in Objective-C?

I was trying to set up a multi thread app. One of the threads is working as background to get some data transfer. Right now this thread automatically kill itself after it's job done.
Somehow I need to kill this thread in another thread in order stop its job immediately. Are there any api or method for making this happen?
In short, you can't. Or, more precisely, you should not. Not ever and not under any circumstances.
There is absolutely no way for thread A to know the exact state of thread B when A kills B. If B is holding any locks or in the middle of a system call or calling into a system framework when A kills it, then the resulting state of your application is going to be nondeterministic.
Actually -- it will be somewhat deterministic in that you are pretty much guaranteed that a crash will happen sometime in the near future.
If you need to terminate thread B, you need to do so in a controlled fashion. The most common way is to have a cancel flag or method that can be set/called. thread B then needs to periodically check this flag or check to see if the method has been called, clean up whatever it is doing, and then exit.
That is, you are going to have to modify the logic in thread B to support this.
bbum is correct, you don't want to simply kill a thread. You can more safely kill a process, because it is isolated from the rest of the system. Because a thread shares memory and resources with the rest of the process, killing it would likely lead to all sorts of problems.
So, what are you supposed to do?
The only correct way of handling this is to have a way for your main thread to send a message to the worker thread telling it to quit. The worker thread must check for this message periodically and voluntarily quit.
An easy way to do this is with a flag, a boolean variable accessible by both threads. If you have multiple worker threads, you might need something more sophisticated, though.
Isn't that a bad idea? (If the other thread is in the middle of doing something in a critical section, it could leave stuff in an inconsistent state.) Couldn't you just set some shared flag variable, and have the other thread check it periodically to see if it should stop?
One thing you could do would be pass messages between the front thread and the background thread, potentially using something like this to facilitate message passing.
If you are using pthread then you try with 'pthread_kill' , I had tried long back it did not worked for me, basically if the thread is in some blocking call it won't work.
It is true that killing a thread is not good option, if you are looking for some kind for fix for some issue then you can try with this.
In my personal view it is best to let a thread run its course naturally. It's difficult to make guarantees about the effect of trying to kill a thread.