How to create a library that uses mutexes only if pthread is linked?

I am creating a C library on Linux that has several functions that work together with some global data. For these functions to be thread safe, they must use mutexes at the appropriate points in the code.

On Linux, to use pthreads in an application, you need to link -lpthread in the appropriate library. In the case of my library assembly, I would like it to work if the user decides to use pthreads in his application, as well as if they do not.

In the case when the developer does not use threads in his application, they will not refer to pthreads. Therefore, I would like my compiled library not to require this, and, in addition, using mutexes in a single-threaded application uses unnecessary overhead (not to mention stupid).

Is there a way to write code (with the GCC extension, if necessary) that a certain block of code will only work if certain characters have been linked? I know I can use dlopen () and friends, but this in itself will require some of what I'm trying to avoid. I assume that what I am looking for should exist, since several standard functions are in the same boat and require that the mutexes are thread safe (and they are), but work even if they are not related to pthreads.

At this point, I notice that the FreeBSD popen () function on lines 66 and 67 uses a non-portable check - isthreaded, to determine if threads are being used or not, and also to use mutexes. I doubt that everything is standardized. But moreover, such code cannot compile and link if characters are not recognized, that in Linux mutex characters will not even be present if pthread is not connected.

To summarize: on Linux, how to create a library that knows when threads are also used, and if so, uses mutexes if necessary and does not require binding to pthreads if the application developer does not want to use threads somewhere?

+2
source share
2

, Linux , ! pthreads, , pthread.

:

#include <stdio.h>
#include <errno.h>
#include <pthread.h>

int main()
{
  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

  if (!(errno = pthread_mutex_lock(&mutex))) { puts("Mutex locked!"); }
  else { perror("Could not lock mutex"); }

  if (!(errno = pthread_mutex_lock(&mutex))) { puts("Mutex locked!"); }
  else { perror("Could not lock mutex"); }

  return 0;
}

pthreads , "Mutex !" . , pthread_mutex_lock() . pthreads ""! .

, , pthreads, (?) , .

+3

:

  • #define , pthreads , : pthread-aware , . , .

  • pthreads , lock unlock,

  • , , .

glibc - - pthreads , . , glitc pthreads. . __libc_maybe_call():

#ifdef __PIC__
# define __libc_maybe_call(FUNC, ARGS, ELSE) \
  (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
                    _fn != NULL ? (*_fn) ARGS : ELSE; }))
#else
# define __libc_maybe_call(FUNC, ARGS, ELSE) \
  (FUNC != NULL ? FUNC ARGS : ELSE)
#endif
0

Source: https://habr.com/ru/post/1612314/


All Articles