>

Tuesday, 15 December 2015

Threading - FAQ

FAQ:

1. Is it possible to use mutex in multiprocessing case on unix?

Mutual exclusion locks (mutexes)  prevent  multiple  threads  from simultaneously executing critical sections of code that access shared data (that is, mutexes are used  to  serialize  the  execution  of  threads).  All mutexes must be global. A  successful call for a mutex lock  by  way  of   mutex_lock()  will  cause  another  thread that is also trying to lock the  same mutex to block until the owner thread unlocks it by way  of   mutex_unlock().  Threads  within  the  same  process or  within other processes can share mutexes.

 Mutexes can synchronize threads within the **same  process**  or  in  ***other   processes***.  Mutexes  can  be used to synchronize  threads between processes if the mutexes  are  allocated  in  writable  memory  and shared among the cooperating processes and have been initialized for this task. Initialize Mutexes are either intra-process or inter-process, depending upon the argument passed implicitly or explicitly to the initialization of that mutex. A statically allocated mutex does not need to be explicitly initialized; by default, a statically allocated mutex is initialized with all zeros and its scope is set to be within the calling process. For inter-process synchronization, a mutex needs to be allocated   in  memory shared between these processes. Since the memory for such a mutex must be allocated dynamically,   the mutex needs to be explicitly initialized using mutex_init().

PTHREAD_PROCESS_SHARED        The  mutex   can   synchronize threads  in  this  process and other  processes.  
 
 
2. Is it a good practice to lock a mutex from the main thread, and release from another thread?
A mutex can only be unlocked by the same thread that locked it. A program that violates this rule has undefined behavior and is not portable or stable; it may seem to work at times and fail horribly at other times, when compiled on a slightly different system, during a different phase of the moon, or after you upgrade.If you really need this sort of behavior (locking by one thread and unlocking by another), a semaphore may meet your needs. Semaphores do not have owners, and any thread may call sem_post or sem_wait at basically any time.

While they can sometimes be used interchangeably, mutexes and semaphores have very different conceptual foundations. The degree to which their actual behavior differs depends on your particular application.
A mutex conceptually has an owner - one thread which, by convention/contract, the programmer treats as the only thread allowed to access the resource(s) which the mutex protects. Depending on the type of mutex it is and the implementation, the owner may be purely a formal construct, or may be an actual field stored in the mutex object. For recursive or error-checking mutexes, for example, storing an owner allows the thread that owns the mutex to obtain additional reference counts on it, or to obtain an error if it tries to re-lock it while the lock is still held, respectively.
A semaphore, on the other hand, is fundamentally a counter. Waiting on a semaphore is not necessarily tied to obtaining exclusive rights to using a resource, although of course that's one potential application (a semaphore which only takes on the values 0 and 1 can be used as a mutex). Semaphores can be used for many other applications, like waiting/signaling - for example, one thread could loop waiting on a semaphore N times to wait for N threads to post to it, where each thread posts when it finishes a task. In fact, a synchronization object equivalent to condition variables can also be implemented in terms of semaphores. They can also be used simply as a portable atomic counter (posting to increment the counter), among many other uses. The "classic" use of a semaphore is to represent the number of available resources from among N equivalent resources, and facilitate waiting when no resources are available, but personally I don't think I've ever used semaphores quite like that.
Now if you want to get into the specifics of POSIX mutexes and semaphores, for the most part semaphores are much more powerful. Not only can they be used for signalling conditions; the post operation is also async-signal-safe meaning you can use it without restriction from inside signal handlers. On the other hand, mutexes do have one feature which cannot be implemented in terms of semaphores: the robust mutex attribute, which allows you to create mutexes that allow other threads/processes to detect and recover when a thread/process terminated while holding the mutex (rather than just deadlocking).

3.What are critical sections in threads

In normal use, a critical section is a section of code that must be executed serially -- i.e., only one thread can execute that code at any given time. You normally accomplish that by protecting the code with a mutex semaphore.
In Windows parlance, a critical section is a data structure (and a few associated functions) that implement at process-specific mutex semaphore (i.e., one that's used only for locking between threads in a single process, not between separate processes).
There are two varieties of semaphores. A mutex semaphore lets only one thread execute at a time. A counted semaphore lets you specify the maximum number of threads that can execute simultaneously. Mutex semaphores are the more common variety, but counted semaphores definitely have uses as well.

4.How to check whether pthread_mutex is locked or not

The following is an outline of one of the methods
void Method1()
{
    try
    {
    pthread_mutex_lock(&syncLock);
    statement1;
    statement2;
    pthread_mutex_unlock(&syncLock);
    statement3;
    statement4;
    }
    catch(exception& e)
    {
    log error
    }
}
where syncLock is of type pthread_mutex_t and is initialized using the default initialization.
My question is that if an exception is thrown in the statement2 of the method then the control passes directly to the catch statement. In that case my mutex remains locked. But I also cant simply write an unlock statement in the catch block since if the exception came from statement 3 then the mutex has been unlocked and calling unlock on an already unlocked mutex results in undefined behavior.
So is there a way I can check whether the mutex has been unlocked or not in the catch statement. Or, is there a C# style lock statement alternative available in c++ so I am sure that the lock is released even if an exception is thrown from within that block
Solution:
Write a tiny RAII-style locker class:
class lock {
    pthread_mutex_t &mutex;
public:  
    lock(pthread_mutex_t &m) :mutex(m) { pthread_mutex_lock(&mutex); }
    ~lock() { pthread_mutex_unlock(&mutex); }
};
Then write your code something like this:
void Method1()
{
    try
    {
        {
            lock l(syncLock);
            statement1;
            statement2;
         }
         statement3;
         statement4;   
    }
    catch(exception& e)
    {
    log error
    }
}
When you exit from the scope where you defined the lock, the lock will be destroyed via the destructor, thus calling pthread_mutex_unlock. That happens whether you exit the scope normally or via an exception. When you enter the exception handler, you know the mutex has been unlocked.
5. Problem:You are given a paragraph , which contain n number of words, you are given m threads. What you need to do is , each thread should print one word and give the control to next thread, this way each thread will keep on printing one word , in case last thread come, it should invoke the first thread. Printing will repeat until all the words are printed in paragraph. Finally all threads should exit gracefully. What kind of synchronization will use?
Solution: Semaphores are used to signal another thread that it's their turn. They are used much less frequently than mutexes, which I guess is why they think it's a good interview question. It's also why the example seems contrived.
Basically, you would create m semaphores. Each thread x waits on semaphore x then posts to semaphore x+1 after doing its thing. In pseudocode:
loop:
    wait(semaphore[x])
    if no more words:
        post(semaphore[(x+1) % m])
        exit
    print word
    increment current word pointer
    post(semaphore[(x+1) % m])




6.What happens to other threads when one thread forks?

In C++ using pthreads, what happens to your other threads if one of your threads calls fork?

Nothing. Only the thread calling fork() gets duplicate. The child process has to start any new threads. The parents threads are left alone.

0 comments:

Post a comment