I have a system with 10+ threads. I have a signal handler to catch SIGSEGV. if one thread generates SIGSEGV, does that signal go to all threads, or just to the thread that generated the signal?
SIGSEGV is a synchronous signal. It'll be delivered to the thread that caused the invalid memory access. From signal(7):
A signal may be generated (and thus pending) for a process as a whole (e.g.,
when sent using kill(2)) or for a specific thread (e.g., certain signals, such
as SIGSEGV and SIGFPE, generated as a consequence of executing a specific
machine-language instruction are thread directed, as are signals targeted at a
specific thread using pthread_kill(3)). A process-directed signal may be
delivered to any one of the threads that does not currently have the signal
blocked. If more than one of the threads has the signal unblocked, then the
kernel chooses an arbitrary thread to which to deliver the signal.
Related
According to the official doc (emphasis mine):
PTHREAD_MUTEX_ROBUST
If the process containing the owning thread of
a robust mutex terminates while holding the mutex lock, the next
thread that acquires the mutex shall be notified about the termination
by the return value [EOWNERDEAD] from the locking function. If the
owning thread of a robust mutex terminates while holding the mutex
lock, the next thread that acquires the mutex may be notified about
the termination by the return value [EOWNERDEAD]...
The doc seems to be differentiating specifically the cases for out-of-process and in-process thread termination and have chosen the wording shall and may carefully. Does this imply that the robustness is mandatory in the out-of-process case, but is optional in the in-process case (which may result in a deadlock)?
If I signal a dispatch semaphore in one thread and wait for it in another thread, is the waiting thread guaranteed to see all changes made by the signalling thread upto a point? If so, is it synchronized at the signalling point or the waiting point?
As the document says:
DISPATCH_QUEUE_PRIORITY_BACKGROUND Items dispatched to the queue will
run at background priority, i.e. the queue will be scheduled for
execution after all higher priority queues have been scheduled and the
system will run items on this queue on a thread with background status
as per setpriority(2) (i.e. disk I/O is throttled and the thread’s
scheduling priority is set to lowest value).
The last part of the document, what does "disk I/O is throttled" mean here?
Does it mean that tasks running at DISPATCH_QUEUE_PRIORITY_BACKGROUND level can't access disk?
What we can deduce from the documentation is that DISPATCH_QUEUE_PRIORITY_BACKGROUND is run on a thread with “background status as per setpriority(2)”.
setpriority(2) has a parameter prio which can be set to either 0 or PRIO_DARWIN_BG. I assume this means that PRIO_DARWIN_BG is used and the documentation describes this as:
When a thread or process is in a background state the scheduling priority is set to the lowest value, disk IO is throttled (with behavior similar to using setiopolicy_np(3) to set a throttleable policy), and network IO is throttled for any sockets opened after going into background state. Any previously opened sockets are not affected.
setiopolicy_np(3) can set the thread I/O policy to IOPOL_IMPORTANT, IOPOL_STANDARD, IOPOL_UTILITY, IOPOL_THROTTLE, or IOPOL_PASSIVE. It describes the effect of throttled disk I/O as:
If a throttleable request occurs within a small time window of a request of higher priority, the thread that issued the throttleable I/O is forced to a sleep for a short period. (Both this
window and the sleep period are dependent on the policy of the throttleable I/O.) This slows down the
thread that issues the throttleable I/O so that higher-priority I/Os can complete with low-latency and
receive a greater share of the disk bandwidth. Furthermore, an IMPORTANT I/O request may bypass a previously
issued throttleable I/O request in kernel or driver queues and be sent to the device first. In
some circumstances, very large throttleable I/O requests will be broken into smaller requests which are
then issued serially.
Which basically means that reading and writing to disk may be slowed or delayed, if another thread with higher priority is also accessing the disk. So no, it does not prevent tasks running at DISPATCH_QUEUE_PRIORITY_BACKGROUND from accessing the disk.
throttling means it controls the rate of I/O based on available resources. On low memery condition it many reduce the number of I/O process, and slows down.
This is quite a general computer science question and not specific to any OS or framework.
So I am a little confused by the overhead associated with switching tasks on a thread pool. In many cases it doesn't make sense to give every job its own specific thread (we don't want to create too many hardware threads), so instead we put these jobs into tasks which can be scheduled to run on a thread. We setup up a pool of threads and then dynamically allocate the tasks to run on a thread taken from the thread pool.
I am just a little confused (can't find a in depth answer) on the overhead associated with switching tasks on a specific thread (in the thread pool). A DrDobbs article (sourced below) states it does but I need a more in depth answer to what is actually happening (a cite-able source would be fantastic :)).
By definition, SomeWork must be queued up in the pool and then run on
a different thread than the original thread. This means we necessarily
incur queuing overhead plus a context switch just to move the work to
the pool. If we need to communicate an answer back to the original
thread, such as through a message or Future or similar, we will incur
another context switch for that.
Source: http://www.drdobbs.com/parallel/use-thread-pools-correctly-keep-tasks-sh/216500409?pgno=1
What components of the thread are actually switching? The thread itself isn't actually switching, just the data that is specific to the thread. What is the overhead associated with this (more, less or the same)?
let´s clarify first 5 key concepts here and then discuss how they correlates in a thread pool context:
thread:
In a brief resume it can be described as a program execution context, given by the code that is being run, the data in cpu registries and the stack. when a thread is created it is assigned the code that should be executed in that thread context. In each cpu cycle the thread has an instruction to execute and the data in cpu registries and stack in a given state.
task:
Represents a unit of work. It's the code that is assigned to a thread to be executed.
context switch (from wikipedia):
Is the process of storing and restoring the state (context) of a thread so that execution can be resumed from the same point at a later time. This enables multiple processes to share a single CPU and is an essential feature of a multitasking operating system. What constitutes the context is as explained above is the code that is being executed, the cpu registries and the stack.
What is context switched is the thread. A task represents only a peace of work that can be assigned to a thread to be executed. At given moment a thread can be executing a task.
Thread Pool (from wikipedia):
In computer programming, the thread pool is where a number of threads are created to perform a number of tasks, which are usually organized in a queue.
Thread Pool Queue:
Where tasks are placed to be executed by threads in the pool. This data structure is a shared peace of memory where threads may compete to queue/dequeue, may lead to contention in high load scenarios.
Illustrating a thread pool usage scenario:
In your program (eventually running in the main thread), you create a task and schedules it to be executed in thread pool.
The task is queued in the thread pool queue.
When a thread from the pool executes it dequeues a task from the pool and starts to executed it.
If there is no free cpus to execute the thread from the pool, the operating system at some point (depending on thread scheduler policy and thread priorities) will stop a thread from executing, context switching to other thread.
the operating system can stop the execution of a thread at any time, context switching to another thread, returning latter to continue where it stopped.
The overhead of the context switching is augmented when the number of active threads that competes for cpus grows. Thus, ideally, a thread pool tries to use the minimum necessary threads to occupy all available cpus in a machine.
If your tasks haven't code that blocks somewhere, context switching is minimized because it is used no more threads than the available cpus on machine.
Of course if you have only one core, your main thread and the thread pool will compete for the same cpu.
The article probably talks about the case in which work is posted to the pool and the result of it is being waited for. Running a task on the thread-pool in general does not incur any context switching overhead.
Imagine queueing 1000 work items. A thread-pool thread will executed them one after the other. All of that without a single context switch in between.
Switching happens doe to waiting/blocking.
I want to create a lot of threads for a writing into a thread, and after writing I call exit... But, when I call exit do I free up the stack or do I still consume it??
In order to avoid resource leaks, you have to do one of these 2:
Make sure some other thread call pthread_join() on the thread
Create the thread as 'detached', which can either be done by setting the proper pthread attribute to pthread_create, or by calling the pthread_detach() function.
Failure to do so will often result in the entire stack "leaking" in many implementations.
The system allocates underlying storage for each thread, (thread ID, thread retval, stack), and this will remain in the process space (and not be recycled) until the thread has terminated and has been joined by other threads.
If you have a thread which you don't care how the thread terminates, and a detached thread is a good choice.
For detached threads, the system recycles its underlying resources automatically after the thread terminates.
source article: http://www.ibm.com/developerworks/library/l-memory-leaks/