3

I have created multiple threads in my application. I want to assign a name to each pthread so I used pthread_setname_np which worked on Ubuntu but is not working on SUSE Linux.

I googled it and came to know '_np' means 'non portable' and this api is not available on all OS flavors of Linux.

So now I want to do it only if the API is available. How to determine whether the api is available or not ? I need something like this.

#ifdef SOME_MACRO
    pthread_setname_np(tid, "someName");
#endif
Ken Keenan
  • 9,818
  • 5
  • 32
  • 49
Srikanth
  • 517
  • 3
  • 10
  • 29

3 Answers3

4

You can use the feature_test_macro _GNU_SOURCE to check if this function might be available:

#ifdef _GNU_SOURCE
    pthread_setname_np(tid, "someName");
#endif

But the manual states that the pthread_setname_np and pthread_getname_np are introduced in glibc 2.12. So if you are using an older glibc (say 2.5) then defining _GNU_SOURCE will not help.

So it's best to avoid these non portable function and you can easily name the threads yourself as part of your thread creation, for example, using a map between thread ID and a array such as:

pthread_t tid[128];
char thr_names[128][256]; //each name corresponds to on thread in 'tid'

You can check the glibc version using:

getconf GNU_LIBC_VERSION
P.P
  • 117,907
  • 20
  • 175
  • 238
  • I am using glibc 2.11.1, so the macro is not working for me.. Anyway thanks. – Srikanth May 20 '15 at 11:32
  • 1
    Isn't `_GNU_SOURCE` a macro you're meant to **set** to use GNU-specific APIs, rather than **read** to test for presence of GNU-specific APIs? – Craig McQueen May 25 '16 at 04:54
  • @CraigMcQueen You're absolutely right. I probably meant, define it to get the GNU specific API and then suggested to *not* use them. Your concern about being variants...I don't see any other way than to check for implementation specific macros. I personally would do what I suggested (name them myself) rather cluttering with ifdefs (but I must admit I never had a situation in which I need to name them in the few pthreads applications I wrote). – P.P May 25 '16 at 07:06
3

Since this function was introduced in glibc 2.12, you could use:

#if ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12)))
    pthread_setname_np(tid, "someName");
#endif
  • Your answer was helpful, if wrong in part. The preprocessor expression should be: `#if (2 < __GLIBC__) || ((2 == __GLIBC__) && (12 <= __GLIBC_MINOR__))` – Preston L. Bannister Nov 04 '19 at 19:44
1

This kind of thing - finding out if a particular function exists in your compilation environment - is what people use GNU Autoconf scripts for.

If your project is already using autoconf, you can add this to your configure source, after the point where you have checked for the pthreads compiler and linker flags:

AC_CHECK_FUNCS(pthread_setname_np)

...and it will define a macro HAVE_PTHREAD_SETNAME_NP if the function exists.

caf
  • 233,326
  • 40
  • 323
  • 462
  • The problem with that is, different platforms have different parameters for the same function name `pthread_setname_np()`. So it's not enough just to test for the presence of the function. See [Can I set the name of a thread in pthreads/Linux?](http://stackoverflow.com/a/7989973/60075) – Craig McQueen May 25 '16 at 04:55
  • Yes, you can use `AC_COMPILE_IFELSE()` instead to test which variant of `pthread_setname_np()` you have. – caf May 25 '16 at 05:15
  • I've just tried the above AC_CHECK_FUNCS() and it doesn't seem to work on a system with glibc-2.19 (Ubuntu 14.04), although I can compile code using the function just fine: `checking for pthread_setname_np... no` Maybe some extra kludge-o-magic is necessary because _GNU_SOURCE needs to be defined? – fencekicker Oct 07 '16 at 14:53
  • @fencekicker: Yes, if you want `_GNU_SOURCE` in an autoconf project you should use the `AC_GNU_SOURCE` macro early in configure, before the compiler is invoked. You won't need to manually define it yourself then, either. – caf Oct 08 '16 at 12:10