As I mentioned in the title, when I try to join the threads, I get an error.
m_threadid : 4615464704, pthread_join error : Resource deadlock avoided, thread name : NetworkWorker
I was wondering what kind of situation it is and any suggestion on fixing this.
Thank you
This error (EDEADLK) results when you have a closed loop of threads trying to join each other. In the simplest cases, this is either a thread calling pthread_join() on itself, or two threads calling pthread_join() on each other.
Related
I am using pthreads and i have this doubt whether a thread will be restarted again if it encounters the same create statement that created it?
Will a thread be restarted again if it encounters the thread_create statement again?
It'll create a new thread regardless of whether it's called by thread that itself was created via pthread_create.
Lets say i have a thread t1. What happens if encounters the create statement, pthread_create(&t1,NULL,func,NULL). How can a new thread be created if i have a unique thread identifier , say the name t1?
In this case, you are still creating new thread but just reusing/overwriting the previous thread identifier t1. Which means you can only call pthread_join on the second you created but lose the ability to pthread_join, change attributes of the first thread, and so on on the first thread. Note that this is still valid. But if this is your use-case, you are probably better off creating detached threads (either by setting the attribute before creating the first thread or by calling pthread_detach from the thread function). A detached thread can't be joined and whose resources are freed when the thread exits (i.e., either by calling pthread_exit or by returning from the thread function).
I'm currently writing an iOS app in Swift, and I encountered the following problem: I have an object A. The problem is that while there is only one thread for the app (I didn't create separate threads), object A gets modified when
1) a certain NSTimer() triggers
2) a certain observeValueForKeyPath() triggers
3) a certain callback from Parse triggers.
From what I know, all the above three cases work kind of like a software interrupt. So as the code run, if NSTimer()/observeValueForKeyPath()/callback from Parse happens, current code gets interrupted and jumps to corresponding code. This is not a race condition (since just one thread), and I don't think something like this https://gist.github.com/Kaelten/7914a8128eca45f081b3 can solve this problem.
There is a specific function B called in all three cases to modify object A, so I'm thinking if I can make this function B atomic, then this problem is solved. Is there a way to do this?
You are making some incorrect assumptions. None of the things you mention interrupt the processor. 1 and 2 both operate synchronously. The timer won't fire or observeValueForKeyPath won't be called until your code finishes and your app services the event loop.
Atomic properties or other synchronization techniques are only meaningful for concurrent (multi-threaded) code. If memory serves, Atomic is only for properties, not other methods/functions.
I believe Parse uses completion blocks that are run on a background thread, in which case your #3 **is* using separate threads, even though you didn't realize that you were doing so. This is the only case in which you need to be worried about synchronization. In that case the simplest thing is to simply bracket your completion block code inside a call to dispatch_async(dispatch_get_main_queue()), which makes all the code in the dispatch_async closure run on the main, avoiding concurrency issues entirely.
I'm getting into NSBlockOperation and I have some questions.
Notably, the documentation for addExecutionBlock says:
Discussion
The specified block should not make any assumptions about
its execution environment.
Calling this method while the receiver is executing or has already
finished causes an NSInvalidArgumentException exception to be thrown.
What kind of situation will throw NSInvalidArgumentException? What really doesn "while receiver is executing" mean? What can cause this?
You can't use addExecutionBlock: to add an execution block while the operation is running or has already completed. That's all it means.
A block operation object can have zero or more execution blocks associated with it. When the block operation is started, all of its associated execution blocks are submitted for concurrent execution. The warning is that you can't add more execution blocks to the operation after this point.
You can create more block operation objects and add execution blocks to those. Each block operation is started separately from others, so the rule about adding more execution blocks is evaluated separately.
Typically, you would create a block operation, add whatever execution blocks to it that you want, and then queue the operation onto an operation queue. Once the operation has been queued, it might start at any time (subject to readiness, which is subject to dependencies). So, it's best to not attempt to add execution blocks once it's been queued.
[NSThread detachNewThreadSelector:#selector(addressLocation:) toTarget:self withObject:parameter];
[self addressLocation:parameter];
Should these two statements do the same thing? Because one of them (the second one) gives me an accurate result, and the other consistently gives me a random location off the coast of Africa. From what I have read, they should both do the same thing; execute addressLocation with the argument 'parameter.' The only difference is the thread, but it is accessing a global volatile variable, so that shouldn't matter, should it?
Threads are much more complicated than that. When you call detachNewThreadSelector, you are creating a new thread, but there's no simple way for you to know when that call completes. It could complete before the next line of code in the calling thread or many seconds later.
If you create the thread first, you can then use performSelector:onThread:withObject:waitUntilDone and you should get the same result as if you used [self addressLocation:parameter]. That won't do you a lot of good though because your main thread will be doing nothing while you wait for the result.
There are lots of ways to get data back from a thread -- I like to call performSelectorOnMainThread from the secondary thread to send the data back to the main thread, for example.
I would read up on Grand Central Dispatch to see if it suits your needs.
In delphi, a method in TThread is terminate. It seems a subthread can not kill another thread by calling terminate or free.
For example
A(main form), B (a thread unit), C (another form).
B is sending data to main form and C (by calling syncronize), we tried to terminate B within C while B is executing by calling B.terminate. But this method does not work and B is still working until it ends in execute method.
Please help. Thank you in advance.
You have to check for Terminate in the thread for this to work. For instance:
procedure TMyThread.Execute;
begin
while not Terminated do begin
//Here you do a chunk of your work.
//It's important to have chunks small enough so that "while not Terminated"
//gets checked often enough.
end;
//Here you finalize everything before thread terminates
end;
With this, you can call
MyThread.Terminate;
And it'll terminate as soon as it finishes processing another chunk of work. This is called "graceful thread termination" because the thread itself is given a chance to finish any work and prepare for termination.
There is another method, called 'forced termination'. You can call:
TerminateThread(MyThread.Handle);
When you do this, Windows forcefully stops any activity in the thread. This does not require checking for "Terminated" in the thread, but potentially can be extremely dangerous, because you're killing thread in the middle of operation. Your application might crash after that.
That's why you never use TerminateThread until you're absolutely sure you have all the possible consequences figured out. Currently you don't, so use the first method.
Actually,
currently most voted answer to this question is incorrect (so as 34 upvoters...) in regard how to forcefully kill a thread.
You do not use ThreadId as a parameter to TerminateThread procedure. Using ThreadId will cause most likely an "Invalid handle" error or in worse case scenerio - will kill a different thread.
You should pass a thread handle as a parameter:
TerminateThread(MyThread.Handle);
More about differences between thread's handle and id can be found here.
Edit
Seems #himself corrected his mistake after seeing my answer, so this is no longer relevant.
Terminate does not kill a thread; it sets the Terminated property to inform the thread that it needs to terminate. It's the thread's responsibility to watch for Terminated and shut itself down gracefully.
All the Terminate method does is it sets the Terminated property to true. So you have to manually keep checking that property and then exit the thread method when it is set to true.
If you might want to terminate a thread then you could be better off spawning another app and killing that if you think its failed - windows will then tidy up after you.