Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Is it ok to wait for an asynchronous request (say an NSURLSessionDataTask,) using a semaphore for example.
There is a lot of advice out there claiming that synchronous networking is bad, however I don't see that as grounds for refusing synchronous requests, especially when they're done in a background thread.
Synchronous requests (in a background thread/queue) have the benefit of not needing to be callback-nested.
The answer in https://stackoverflow.com/a/31563134/466604 shows only a method to achieve this, but it comes with implied discouragement. (Along with other discouragement from https://devforums.apple.com/thread/9606?tstart=0)
My question is whether discouraging this discouragement is warranted, given those synchronous requests happen in a background thread, primarily as a way to avoid nesting callbacks.
No, it's not ok. Don't do this.
iOS might even kill your app in the process. Besides, look at callbacks as they were the next step in your serial execution.
The processor needs those cycles to do other things, don't be a bully!
INSIGHT:
As #EricD said, if your execution fails for some reason, that thread is lost until you exit your app and the O.S. claims it back.
That thread is a valuable resource that must not be wasted and much
more valuable in Mobile Operating Systems as iOS.
iPhone's processors are not as powerful as nowadays Desktop' processors or GPU's processors that can build up to hundreds of thousands threads.
If you use a semaphore, you are waking up to ask that thread after some time, and if the conditions has not being met, then you go to sleep again. This is usually in the ms time, but still, is some time that the processor dedicate to something useless.
MORE CLEAR
When you define a callback, is as if you were to sleep and you say to somebody.
Don't call me, I will call you when I'm ready to go.
Instead, using a semaphore is like:
Is ok if you call me 1000..0 times to ask me if I'm ready to go
The overheading in this case is obvious...you usually needs a time to wake up and to sleep back again. That's wasted processor time
Keep in mind that in the best case you are using a semaphore that put the Thread into sleep for a while, and then ask again if it is OK to proceed.
If this is not the case, then this thread is using ALL the processor cycles assigned to it to ask you if it's ok to proceed, that is 100% CPU Usage in that Thread evaluating just a condition.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I'm learning how to parse JSON from web APIs. I have read that I need to asynchronously return my parsed data from the API for my application, as opposed to synchronously. I'm not sure why it has to be asynchronously. I know it has something to do with threading, but that doesn't clarify it for me.
Why do network requests have to be performed asynchronously?
The fact that you should to do this asynchonously has nothing to do with the nature of the response (JSON or otherwise). It’s just that you’re requesting data from an API on a remote server and you don’t know how long it will take (subject to the nature of the network the device is on, how busy the web server is, etc.).
Bottom line, any task that takes more than a few milliseconds should generally be performed asynchronously to ensure a responsive UI, and this API call will take much more time than that.
Analogy time
Imagine that you're employed in the information booth of a train station to manually update a board with trains' statuses. You read off an old-fashioned ticker tape and move models of the trains around so that passengers can see what's going on. You also answer questions about schedules and such directly, when passengers ask you.
You realize that for one particular portion of the board, some information is missing from your tape. Your colleague has the info, but she isn't in the station. So you leave the board, go over to the phone, and call her. You dial, and wait for her to pick up, and then explain what you need. She doesn't have what you need immediately to hand, so she asks you to wait a moment while she gets it.
Meanwhile, the tape doesn't stop. Information about trains continues to come in. but because you're sitting there on the phone waiting, you're not doing anything with it. The people who are watching the board get frustrated, and the people who have questions for you can't ask them either.
Finally, your colleage comes back and gives you what you asked for. You thank her and return to the board. You realize the board is in very bad shape, not reflecting the current state of the world at all. And the passengers with questions have stormed out and left you a one-star review on the App, I mean Train, Store.
Next day, the same situation comes up. You need information you don't have. Instead of stepping away from the board for several minutes, you quickly fire off a text message, and get right back to talking to passengers and moving things around on the board.
In about the same amount of time that you spent waiting on the phone yesterday, you get a text back from your colleague with the information. You incorporate it into your workflow, and nobody even notices that you spend a couple of seconds reading from your phone instead of the ticker tape. Victory!
The first day, you made a synchronous network request. You initiated a conversation with a remote service and waited until you got the response. When that happened, your UI was locked up, neither taking input from the user nor refreshing its own state.
The second day, you made an asynchronous request. You kept working normally until the response came back, allowing you to continue with all your other tasks.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Can we create multiple main thread in single application?
Why all UI changes made in main thread?
I have faced these question in interviews. I am unable to find any solution. Can any one help me to find the answers of this question? That will help me in future interviews and implementations in iOS app.
Thanks in advance!
There is only ever one main thread in your application, however tasks from multiple dispatch queues may execute on this thread. Tasks that are dispatched on the main queue are guaranteed to run on the main thread.
Generally with GCD you do not think about threads, but rather queues which are abstracted from the underlying threads. They provide a level of abstraction that makes it easier to manage tasks without being concerned about the number or state of the threads that are being used.
THe autolayout engine performs a number of calculations and applies rules in order to arrive at a layout solution. If the properties of a UI element change then the autolayout solution is invalidated and needs to be recalculated.
As the main queue is a serial dispatch queue, dispatching UI updates onto the main queue ensures that either the autolayout calculations are being performed or a UI property is being updated but not both at the same time (of course there are more than just these two activities happening on the main queue, but we are just addressing autolayout here)
No, there is only one main thread for the application that is created by system for application. Main thread is the thread that directly gives changes to user. Thread which is directly connect with user you can said.
Check the Apple Documentation, It states,
The main queue is automatically created by the system and associated with your application’s main thread. Your application uses one (and only one) of the following three approaches to invoke blocks submitted to the main queue:
Calling dispatch_main
Calling UIApplicationMain (iOS) or NSApplicationMain (OS X)
Using a CFRunLoopRef on the main thread
As with the global concurrent queues, calls to dispatch_suspend,
dispatch_resume, dispatch_set_context, and the like have no effect
when used with queues returned by this function.
Now, let's take an example, If you are downloading an image and want to display it to user. Now if you will download it on main thread then it will block other UI till it completed download. So, you should not download it on main thread or synchronously . you should download it asynchronously and when download is completed, you should display it to user on main thread, so it will quick displayed to user after download is completed.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I want to have some clarify about it.
I know that I need to update UI in main thread. Are there anything else?
What I need to do in main thread and what in background threads?
In addition to UI updates, as a broader thread-safety strategy, people will often dispatch their model updates to the main thread as a simple synchronization technique, too.
Synchronization is ultimately the process of assuring that an object is in a logically consistent state, i.e. that while an object is being used on one thread, that it isn't simultaneously being mutated by some other thread. Traditionally, one might accomplish this by employing locks (e.g. NSLock, #synchronized, etc.) but you can also achieve this by dispatching all interaction with a particular object to a serial queue. While you can replace locks with a dedicated serial queue, in many cases it's just as easy to dispatch all updates to the object in the main queue. It turns out to be a convenient way to synchronize your model objects that might otherwise would have been used/mutated by separate threads.
For more information, see the Eliminating Lock-Based Code section in the Migrating Away from Threads chapter of the Concurrency Programming Guide.
It all depends.
Modern OS take advantage of the multiple cores or virtual CPUs, so when you run your app, the OS defines what to run where, and usually your program runs in multiple threads.
If there are data dependencies, then you should run things in specific threads, unless you run stuff in background or different threads, then you can implement notifications to ensure that the data you need is ready when you need it. You should also take into account the thread safe nature of the the different ways to define properties. So... other than the UI stuff in main, you can run anything pretty much wherever you want.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Tell me if this make sense. This is an iOS question.
I'm seeing code where it is already in the main thread, but the code would dispatch_async all sorts of UI code to the main thread's queue. Layouts, animations etc etc.
I was told this some how speeds up responsiveness (example, when pushing a view controller, you would dispatch other UI ops there so it won't block the push transition.
This doesn't make sense because first it is dangerous, second, it doesn't guarantee when the UI code gets run(even though it will probably run with milliseconds). The only good reason I can see is for it to guarantee that the UI code is not accidentally run in a different thread.
What do you guys think?
There are definitely times you employ this pattern of dispatching back to the main queue, so I might not be too quick to dismiss it or label it as "dangerous" (though the way you characterize it, it does sound suspicious). You should share some code samples of how you're seeing this pattern being used, and we can comment further.
When would you dispatch to the main queue? The prototypical example is when you're doing something on a background queue, but then want to dispatch the UI updates back to the main queue, e.g.:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// do something time consuming here, like network request or the like
// when done, update the UI on the main queue:
dispatch_async(dispatch_get_main_queue(), ^{
// update the UI here
});
});
But I'm assuming this is not the sort of dispatch to the main queue you're talking about. I'm assuming from your comment where you have something on the main queue dispatching asynchronously right back to the main queue itself.
The reason you would do that is if you don't want the dispatched code to run immediately, but rather to be queued for the next iteration of the run loop. This lets the autorelease pool drain, lets the current method complete (and release any resources it might have been using), lets other dispatched tasks run first, gives the UI a chance to reflect any changes you may have initiated, etc.
A few examples of when some developers might do this include:
You might use this pattern if you want a method call itself recursively, but you want to yield back to the run loop, to let resources be freed, let the UI reflect any changes, etc. You're basically saying "ok, let this method finish, but in the next run loop, run this method again."
A little more suspect, I've seen this pattern in viewDidLoad where you want to give auto layout a chance to "catch up" and update the frames. E.g. there is a common third-party progress indicator that won't work if you just invoke it from viewDidLoad, but it works if you dispatch that update back to the main queue.
Having articulated reasons why I've seen developers dispatch back to the main queue from the main queue, itself, I must confess that many of these patterns suffer from code smell and are often better accomplished via different patterns. But these are a few examples that I've seen.
But, again, if you want assistance on your particular code sample, you have to share it with us. We can't tell what the developer intended without seeing the code sample.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
How to stop long executing threads gracefully?
Hello.
I have a background thread which needs to perform an operation, it works fine all of the time except in one case : when the resource is corrupted. When that happens the thread gets Blocked in the Load (to that resource) calls in the Execute method.
When that happens the thread Won't respond to the Terminate method ( call from main thread ) and gets blocked.
So, my question is : How to properly terminate the blocked thread ( from the main thread ). And no I cannot modify the class which loads the resource, or neither know from before if the resource is corrupted or not.
Look for TerminateThread() WinAPI function.
Some useful explanation can be found here or look at MSDN documentation.
Of course, after terminating you must look if any resources allocated in thread not freed and free it appropriately.
Update
Yes, using TerminateThread is bad practice (as specified in comments). I'm agree with this opinion. But "never use it, even if you really need to use it" recomendation it too strong from my point of view and very theoretic. Real world full of design flaws and buggy 3rd-party libraries.
Information, given in question not enough for making right decision about this concrete situation. E.g. it may be temporary workaround with no alternatives, etc.
Therefore, from theoretic point of view right answer is : "There are no way to terminate process properly if you can't control how to "freezing" step in background thread processed."
From practical point of view right answer is: "There are no way to terminate process properly if you can't control how to "freezing" step in background thread processed. But if you realize that you can't, but still needs such functionality - use TerminateThread() API call"
About TerminateThread vs. TerminateProcess:
- Creating/terminating process requires more resources than creating/terminating thread
- Creating/terminating process more complicated => more place for bugs
- TerminateProcess don't terminates immediately and waits for I/O operations to complete (MSDN) => not a choice for scenario where remote shared folder becomes unavailable while reading and other similar I/O scenarios.
- Creating and terminating process requires more user privileges than creating thread, compare MSDN here and here
About resource freeing:
Thread stack freed automatically when terminating thread (as mentonied in MSDN). Resources is primarily resources, allocated by main thread for communication with background thread. E.g. memory structures, mutexes, etc.