what is the "attribute" of a pthread mutex? - attributes

The function pthread_mutex_init allows you to specify a pointer to an attribute. But I have yet to find a good explanation of what pthread attributes are. I have always just supplied NULL. Is there a use to this argument?
The documentation, for those of you who forget it:
PTHREAD_MUTEX_INIT(3) BSD Library
Functions Manual
PTHREAD_MUTEX_INIT(3)
NAME
pthread_mutex_init -- create a mutex
SYNOPSIS
#include <pthread.h>
int
pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
DESCRIPTION
The pthread_mutex_init() function creates a new mutex, with attributes
specified
with attr. If attr is NULL, the default attributes are used.

The best place to find that information is from the POSIX standards pages.
A NULL mutex attribute gives you an implementation defined default attribute. If you want to know what you can do with attributes, check out the following reference and follow the pthread_mutexattr_* links in the SEE ALSO section. Usually, the default is a sensible set of attributes but it may vary between platforms, so I prefer to explicitly create mutexes with known attributes (better for portability).
This is for issue 7 of the standard, 1003.1-2008. The starting point for that is here. Clicking on Headers in the bottom left will allow you to navigate to the specific functionality (including pthreads.h).
The attributes allow you to set or get:
the type (deadlocking, deadlock-detecting, recursive, etc).
the robustness (what happens when you acquire a mutex and the original owner died while possessing it).
the process-shared attribute (for sharing a mutex across process boundaries).
the protocol (how a thread behaves in terms of priority when a higher-priority thread wants the mutex).
the priority ceiling (the priority at which the critical section will run, a way of preventing priority inversion).
And, for completeness, there's the init and destroy calls as well, not directly related to a specific attribute but used to create them.

All mutex attributes are set in a mutex attribute object by a function of the form:
int pthread_mutexattr_setname(pthread_attr_t *attr, Type t);
All mutex attributes are retrieved from a mutex attribute object by a function of the form:
int pthread_mutexattr_getname(const pthread_attr_t *attr, Type *t);
where name and Type are defined as in the table below:
Type and Name Description and Value(s)
int protocol Define the scheduling classes for mutex locks
PTHREAD_PRIO_NONE,PTHREAD_PRIO_PROTECT,
PTHREAD_PRIO_INHERIT
int pshared Defines whether a mutex is shared with other processes.
PTHREAD_PROCESS_SHARED, PTHREAD_PROCESS_PRIVATE
int prioceiling Used for mutex attribute priority ceiling values.
See POSIX.1 section 13
int type Application defined mutex locking
PTHREAD_MUTEX_NORMAL,PTHREAD_MUTEX_RECURSIVE,
PTHREAD_MUTEX_ERRORCHECK,PTHREAD_MUTEX_DEFAULT

If you scroll down the function listing for <pthread.h>, you will find a bunch of pthread_mutexattr_... functions, including an init, destroy and functions to set various attributes of a mutex. When you pass NULL, the mutex is created with suitable defaults for all these attributes, but if you need to modify specific attributes, you can construct a pthread_mutexattr_t structure and pass it in.

Applying NULL to this argument implies using the default argument.
So for some reasons you could want to change these default settings (using pthread_mutexattr_init).
The documentation explains all you need about these mutex settings.

Related

can pthread_mutexattr_setrobust apply to pthread_rwlock_t?

the robustness of mutex is very important to my program since it can handle the case when a process died without releasing the mutex.
But according to the document, pthread_mutexattr_setrobust only apply to pthread_mutex_t, instead of pthread_rwlock_t, is there any approach to set the robustness of pthread_rwlock_t? Or its implementation is robust by default?
according to the document, pthread_mutexattr_setrobust only apply to pthread_mutex_t
More precisely, pthread_mutexattr_setrobust() sets a property of a pthread_mutexattr_t object, and these are used (only) for configuring objects of type pthread_mutex_t. This happens at initialization of the mutex via pthread_mutex_init().
The corresponding initialization function for read/write locks is pthread_rwlock_init(), and its documentation shows that the corresponding attribute object type, accepted by that function, is pthread_rwlockattr_t. Implementations may provide whatever properties they like as extensions, but the only one specified for this type by the current version of POSIX is pshared. Thus no, there is no (portable) robustness option for pthreads read/write locks.

Alternate to setpriority(PRIO_PROCESS, thread_id, priority)

Given - Thread id of a thread.
Requirement - Set Linux priority of the thread id.
Constraint - Cant use setpriority()
I have tried to use below
pthread_setschedprio(pthread_t thread, int prio);
pthread_setschedparam(pthread_t thread, int policy,
const struct sched_param *param);
Both the above APIs use pthread_t as an argument. I am not able to construct (typecast) pthread_t from thread id. I understand converting this is not possible due to different types.
Is there a way to still accomplish this ?
Some aspects of the pthread_setschedprio interface are available for plain thread IDs with the sched_setparam function (declared in <thread.h>). The sched_setparam manual page says that the process is affected (which is the POSIX-mandated behavior), but on Linux, it's actually the thread of that ID.
Keep in mind that calling sched_setparam directly may break the behavior expected from PI mutexes and other synchronization primitives because the direct call does not perform the additional bookkeeping performed by the pthread_* functions.

A thread_guard Equivalent To lock_guard / unique_lock

The standard library provides a mutex class, with the ability to manually lock and unlock it:
std::mutex m;
m.lock();
// ...
m.unlock();
However, the library apparently also recognizes that a common case is just to lock the mutex at some point, and unlock it when leaving a block. For this it provides std::lock_guard and std::unique_lock:
std::mutex m;
std::lock_guard<std::mutex> lock(m);
// ...
// Automatic unlock
I think a fairly common pattern for threads, is to create one (either as a stack variable, or a member), then join it before destructing it:
std::thread t(foo);
// ...
t.join();
It seems easy to write a thread_guard, which would take a thread (or a sequence of threads), and would just call join on its own destruction:
std::thread t(foo);
thread_guard<std::thread> g(t);
// ...
// Join automatically
Is there a standard-library class like it?
If not, is there some reason to avoid this?
This issue is discussed in Scott Meyer's book "Modern Effective c++"
The problem is that if there would be another default behavior (detach or join) would cause hard to find errors in case you forget that there is a implicit operation. So the actual default behavior on destruction is asserting if not explicitly joined or detached. And no "Guard" class is there also because of that reason.
If you always want to join it's safe to write such a class yourself. But when someone uses it and wants to detach people can forget that the destructor will implicitly join it. So that's the risk in writing such function.
As an alternative you can use a scope_guard by boost or the folly library (which I personally prefer more) and declare in the beginning explicitly your intention and it will be executed. Or you can write a policy based "Guard" class where you have to explicitly state what you want to do on destruction.

pthread concepts in linux

I have some questions about pthreads in linux:
Is it the case that pthread_t is it a datatype similar to int and char indicating we are defining a thread?
If so, how much size does it take? 2 bytes or 4 bytes?
Does the compiler allocate memory to pthread_t thread1 immediately after that statement or does it wait until it a pthread_create() call?
How does one set the thread attributes, and what is their typical use?
Can one only pass more than one argument in the pthread_create() call? If so, how?
I have lots of things on my mind like this. Please also feel free to suggest any good sites or documents to read.
Answering the questions one by one, though not necessarily in the same order:
Is pthread_t a data type similar to int or char, indicating we are defining a thread ? Does the compiler allocate memory to pthread_t thread1 immediately after that sentence or does it wait until it finds the pthread_create() call
pthread_t is a type similar to int and it's created when you define it, not when you call pthread_create. In the snippet:
pthread_t tid;
int x = pthread_create (&tid, blah, blah, blah);
it's the first line that creates the variable, although it doesn't hold anything useful until the return from pthread_create.
How much size does a pthread_t take, 2 bytes or 4 bytes?
You shouldn't care how much space it takes, any more than you should care how much space is taken by a FILE structure. You should just use the structure as intended. If you really want to know, then sizeof is your friend.
Any good information about how to set the thread attributes?
If you want to use anything other than default attributes, you have to create an attributes variable first and then pass that to the pthread_create call.
Can we only pass one argument in the pthread_create function to the function? Can't we send 2 or 3 arguments in the pthread_create() function to the called thread?
While you're only allowed to pass one extra parameter to the thread , there's nothing stopping you from making this one parameter a pointer to a structure holding a hundred different things.
If you're looking for information on how to use pthreads, there's plenty of stuff at the end of a Google search but I still prefer the dead-tree version myself:
how much size does it take
pthread_t uses sizeof pthread_t bytes.
and we can only pass one argument in the pthread_create to the function not more than one? cant we send 2 or 3 arguments in the pthread_create() function to the called thread?
All you need is one argument. All you get is one argument. It's a void * so you can pass a pointer to whatever you want. Such as a structure containing multiple values.
i have lots of things on my mind like this suggest any good sites or documents to read
Have a look at the pthread man pages, online or in your shell of choice (man pthread, man pthread_create, etc.). I started out reading some basic lecture slides (here's the sequel).
pthread_t could be any number of bytes. It could be a char, an int, a pointer, or a struct... But you neither need to know nor to care. If you need the size for allocation purposes, you use sizeof(pthread_t). The only type of variable you can assign it to is another pthread_t.
The compiler may or may not allocate the resources associated with the thread when you define a pthread_t. Again, you do not need to know nor to care, because you are required to call pthread_join (or pthread_detach) on any thread you create. As long as you follow the rules, the system will make sure it does not leak memory (or any other resource).
Attributes are admittedly a bit clumsy. They are held in an pthread_attr_t object, which again could be represented as an integer, pointer, or entire struct. You have to initialize it with pthread_attr_init and destroy it with pthread_attr_destroy. Between those two, you use various pthread_attr_... calls to set or clear attributes, and then you can pass it as part of one or more pthread_create calls to set the attributes of the new threads.
Different implementations can and will handle all of these things differently.
LLNL has a decent set of introductory information.
Look into pthread.h file to get more information. On my system, pthread_t is defined as an unsigned long int. But I guess this is platform dependent, since it is defined into bits/pthreadtype.h.

How are mutex created on Linux?

I'd like to know how are mutex created on Linux? I figured out, that pthread_mutex_init() doesn't change value of pthread_mutex_t variable, so how it "create" mutex?
Does it mark this variable as some kind of system resource or what?
I was implementing R-value constructor for class, which have a pthread_mutex_t field in it's body and I don't know how to move mutex frome one class to another...
You can see what pthread_mutex_init does here (warning, you brain will hurt).
It does memset() the mutex.
However, mutexes are implemented on top of the futex calls. This works on memory addresses, i.e.
the address of one of the pthread_mutex_t members is used as a system resource.
This means you cannot copy/move a pthread_mutex_t.
It seems like you want to pass ownership of the mutex to another class. Are you sure that is the correct way to solve your problem? If you absolutely need to do it though, you could create an auto_ptr to pass ownership around:
class A
{
A(const A & other) mutex(other.mutex) { /* ... */ }
auto_ptr<pthread_mutex_t> mutex;
}

Resources