mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-27 15:41:05 +08:00
Problem: ZMQ background threads are unnamed
Solution: use pthread API to set the name. For now call every thread "ZMQ b/g thread". Would be nice to number the I/O threads and name explicitly the reaper thread, but in reality a bit of internal API churn would be necessary, so perhaps it's not worth it. This is useful when debugging a process with many threads.
This commit is contained in:
parent
3548d5e950
commit
3ab4796c5a
@ -323,6 +323,7 @@ zmq_check_tcp_keepidle ()
|
|||||||
zmq_check_tcp_keepintvl ()
|
zmq_check_tcp_keepintvl ()
|
||||||
zmq_check_tcp_keepalive ()
|
zmq_check_tcp_keepalive ()
|
||||||
zmq_check_tcp_tipc ()
|
zmq_check_tcp_tipc ()
|
||||||
|
zmq_check_pthread_setname ()
|
||||||
|
|
||||||
|
|
||||||
if ( CMAKE_SYSTEM_NAME MATCHES "Linux"
|
if ( CMAKE_SYSTEM_NAME MATCHES "Linux"
|
||||||
|
@ -176,3 +176,55 @@ int main(int argc, char *argv [])
|
|||||||
"
|
"
|
||||||
ZMQ_HAVE_TIPC)
|
ZMQ_HAVE_TIPC)
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
macro(zmq_check_pthread_setname)
|
||||||
|
message(STATUS "Checking pthread_setname signature")
|
||||||
|
set(SAVE_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "-D_GNU_SOURCE -Werror -pthread")
|
||||||
|
check_c_source_runs(
|
||||||
|
"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv [])
|
||||||
|
{
|
||||||
|
pthread_setname_np (\"foo\");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
ZMQ_HAVE_PTHREAD_SETNAME_1)
|
||||||
|
check_c_source_runs(
|
||||||
|
"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv [])
|
||||||
|
{
|
||||||
|
pthread_setname_np (pthread_self(), \"foo\");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
ZMQ_HAVE_PTHREAD_SETNAME_2)
|
||||||
|
check_c_source_runs(
|
||||||
|
"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv [])
|
||||||
|
{
|
||||||
|
pthread_setname_np (pthread_self(), \"foo\", (void *)0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
ZMQ_HAVE_PTHREAD_SETNAME_3)
|
||||||
|
check_c_source_runs(
|
||||||
|
"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv [])
|
||||||
|
{
|
||||||
|
pthread_set_name_np (pthread_self(), \"foo\");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
ZMQ_HAVE_PTHREAD_SET_NAME)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS ${SAVE_CMAKE_REQUIRED_FLAGS})
|
||||||
|
endmacro()
|
||||||
|
@ -29,6 +29,10 @@
|
|||||||
#cmakedefine ZMQ_HAVE_TCP_KEEPIDLE
|
#cmakedefine ZMQ_HAVE_TCP_KEEPIDLE
|
||||||
#cmakedefine ZMQ_HAVE_TCP_KEEPINTVL
|
#cmakedefine ZMQ_HAVE_TCP_KEEPINTVL
|
||||||
#cmakedefine ZMQ_HAVE_TCP_KEEPALIVE
|
#cmakedefine ZMQ_HAVE_TCP_KEEPALIVE
|
||||||
|
#cmakedefine ZMQ_HAVE_PTHREAD_SETNAME_1
|
||||||
|
#cmakedefine ZMQ_HAVE_PTHREAD_SETNAME_2
|
||||||
|
#cmakedefine ZMQ_HAVE_PTHREAD_SETNAME_3
|
||||||
|
#cmakedefine ZMQ_HAVE_PTHREAD_SET_NAME
|
||||||
|
|
||||||
#cmakedefine ZMQ_HAVE_OPENPGM
|
#cmakedefine ZMQ_HAVE_OPENPGM
|
||||||
#cmakedefine ZMQ_MAKE_VALGRIND_HAPPY
|
#cmakedefine ZMQ_MAKE_VALGRIND_HAPPY
|
||||||
|
50
configure.ac
50
configure.ac
@ -589,6 +589,56 @@ AC_TYPE_SIGNAL
|
|||||||
AC_CHECK_FUNCS(perror gettimeofday clock_gettime memset socket getifaddrs freeifaddrs fork posix_memalign mkdtemp)
|
AC_CHECK_FUNCS(perror gettimeofday clock_gettime memset socket getifaddrs freeifaddrs fork posix_memalign mkdtemp)
|
||||||
AC_CHECK_HEADERS([alloca.h])
|
AC_CHECK_HEADERS([alloca.h])
|
||||||
|
|
||||||
|
# pthread_setname is non-posix, and there are at least 4 different implementations
|
||||||
|
AC_MSG_CHECKING([whether signature of pthread_setname_np() has 1 argument])
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <pthread.h>]],
|
||||||
|
[[pthread_setname_np ("foo"); return 0;]])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(ZMQ_HAVE_PTHREAD_SETNAME_1, [1],
|
||||||
|
[Whether pthread_setname_np() has 1 argument])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
AC_MSG_CHECKING([whether signature of pthread_setname_np() has 2 arguments])
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <pthread.h>]],
|
||||||
|
[[pthread_setname_np (pthread_self (), "foo"); return 0;]])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(ZMQ_HAVE_PTHREAD_SETNAME_2, [1],
|
||||||
|
[Whether pthread_setname_np() has 2 arguments])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
AC_MSG_CHECKING([whether signature of pthread_setname_np() has 3 arguments])
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <pthread.h>]],
|
||||||
|
[[pthread_setname_np (pthread_self(), "foo", (void *)0); return 0;]])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(ZMQ_HAVE_PTHREAD_SETNAME_3, [1],
|
||||||
|
[Whether pthread_setname_np() has 3 arguments])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
AC_MSG_CHECKING([whether pthread_set_name_np() exists])
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <pthread.h>]],
|
||||||
|
[[pthread_set_name_np (pthread_self(), "foo"); return 0;]])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(ZMQ_HAVE_PTHREAD_SET_NAME, [1],
|
||||||
|
[Whether pthread_set_name_np() exists])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
|
||||||
LIBZMQ_CHECK_SOCK_CLOEXEC([
|
LIBZMQ_CHECK_SOCK_CLOEXEC([
|
||||||
AC_DEFINE([ZMQ_HAVE_SOCK_CLOEXEC],
|
AC_DEFINE([ZMQ_HAVE_SOCK_CLOEXEC],
|
||||||
[1],
|
[1],
|
||||||
|
@ -412,6 +412,7 @@ void zmq::ctx_t::start_thread (thread_t &thread_, thread_fn *tfn_, void *arg_) c
|
|||||||
{
|
{
|
||||||
thread_.start(tfn_, arg_);
|
thread_.start(tfn_, arg_);
|
||||||
thread_.setSchedulingParameters(thread_priority, thread_sched_policy);
|
thread_.setSchedulingParameters(thread_priority, thread_sched_policy);
|
||||||
|
thread_.setThreadName ("ZMQ b/g thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmq::ctx_t::send_command (uint32_t tid_, const command_t &command_)
|
void zmq::ctx_t::send_command (uint32_t tid_, const command_t &command_)
|
||||||
|
@ -77,6 +77,12 @@ void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_
|
|||||||
LIBZMQ_UNUSED (schedulingPolicy_);
|
LIBZMQ_UNUSED (schedulingPolicy_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zmq::thread_t::setThreadName(const char *name_)
|
||||||
|
{
|
||||||
|
// not implemented
|
||||||
|
LIBZMQ_UNUSED (name_);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -159,4 +165,23 @@ void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zmq::thread_t::setThreadName(const char *name_)
|
||||||
|
{
|
||||||
|
if (!name_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if defined(HAVE_PTHREAD_SETNAME_1)
|
||||||
|
int rc = pthread_setname_np(name_);
|
||||||
|
posix_assert (rc);
|
||||||
|
#elif defined(HAVE_PTHREAD_SETNAME_2)
|
||||||
|
int rc = pthread_setname_np(descriptor, name_);
|
||||||
|
posix_assert (rc);
|
||||||
|
#elif defined(HAVE_PTHREAD_SETNAME_3)
|
||||||
|
int rc = pthread_setname_np(descriptor, name_, NULL);
|
||||||
|
posix_assert (rc);
|
||||||
|
#elif defined(HAVE_PTHREAD_SET_NAME)
|
||||||
|
pthread_set_name_np(descriptor, name_);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,6 +67,10 @@ namespace zmq
|
|||||||
// pthread. Has no effect on other platforms.
|
// pthread. Has no effect on other platforms.
|
||||||
void setSchedulingParameters(int priority_, int schedulingPolicy_);
|
void setSchedulingParameters(int priority_, int schedulingPolicy_);
|
||||||
|
|
||||||
|
// Sets the thread name, 16 characters max including terminating NUL.
|
||||||
|
// Only implemented for pthread. Has no effect on other platforms.
|
||||||
|
void setThreadName(const char *name_);
|
||||||
|
|
||||||
// These are internal members. They should be private, however then
|
// These are internal members. They should be private, however then
|
||||||
// they would not be accessible from the main C routine of the thread.
|
// they would not be accessible from the main C routine of the thread.
|
||||||
thread_fn *tfn;
|
thread_fn *tfn;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user