Выявление, какие потоки владеют pthread_rwlock_t -- multithreading пол Связанный проблема

Finding out which threads own a pthread_rwlock_t


3
vote

проблема

русский

Как я могу увидеть (на Linux), какие потоки владеют pthread_rwlock_t (или std :: shared_mutex)?

Для обычного mutex есть это возможно Определите нить удерживания Mutex? Но как это сделать для блокировки Ar / W?

Английский оригинал

How can I see (on linux) which threads own a pthread_rwlock_t (or std::shared_mutex) ?

For a regular mutex there's Is it possible to determine the thread holding a mutex? but how to do this for a r/w lock?

</div
  

Список ответов

1
 
vote
vote
Лучший ответ
 

Ваш хороший вопрос имеет несколько проблем с полным ответом:

  1. это зависит от того, какое ядро ​​ОС вы работаете, и, возможно, даже какую версию.
  2. это зависит от того, какое libc / libpthread вы используете, и, возможно, даже какой компилятор.

Предполагается, что вы можете распутать определенную конфигурацию выше, мы смотрим на два разных результата: есть один em> писатель или набор читателей , который в настоящее время вызывает pthread_rw_lock ( ) блокировать для некоторых абонентов. Напротив, Mutex имеет только один из владельца и только что владелец может отпустить его.

Поэтому первый тест, выясняя, имеет ли ваша система нажимаемым набором владельца, состоит в том, чтобы увидеть, действительно ли он записывает право собственности. Быстрый взлом для этого будет иметь один поток, приобретенный rwlock для чтения или записи, затем сигнализирует о втором, чтобы освободить его. Если выпуск не удается, ваша реализация правильно записывает его, и у вас есть шанс; Если нет, ваша реализация, вероятно, реализует Rwlocks с Mutex + Condvar + счетчик; Так что не имеет представления о владельце.

Так, какой код:

 <код> #include <stdio.h> #include <pthread.h>  pthread_mutex_t lock; pthread_cond_t cv; pthread_rwlock_t rwl; int ready;  void *rlse(void *_) {     int *t = _;     pthread_mutex_lock(&lock);     while (ready == 0) {         pthread_cond_wait(&cv, &lock);     }     ready = 0;     pthread_cond_signal(&cv);     pthread_mutex_unlock(&lock);     *t = pthread_rwlock_unlock(&rwl);     return 0; }  void *get(void *_) {     int *t = _;     *t = (*t) ? pthread_rwlock_wrlock(&rwl) : pthread_rwlock_rdlock(&rwl);     if (*t == 0) {         pthread_mutex_lock(&lock);         ready = 1;         pthread_cond_signal(&cv);         while (ready == 1) {             pthread_cond_wait(&cv, &lock);         }         pthread_mutex_unlock(&lock);     }     return 0; }  int main() {     pthread_t acq, rel;     int v0, v1;     int i;     for (i = 0; i < 2; i++) {         pthread_rwlock_init(&rwl, 0);         pthread_mutex_init(&lock, 0);         pthread_cond_init(&cv, 0);         v0 = i;         pthread_create(&acq, 0, get, &v0);         pthread_create(&rel, 0, rlse, &v1);         pthread_join(acq, 0);         pthread_join(rel, 0);         printf("%s: %d %d ", i ? "write" : "read", v0, v1);     }     return 0; }   

Что мы проводим как:

 <код> u18:src $ cc rw.c -lpthread -o rw u18:src $ ./rw read: 0 0 write: 0 0   

Это говорит нам, что в любом случае (rdlock, wrlock), нить, отличный от вызова нити, может отпустить rwlock, поэтому он принципиально не имеет владельца.

с небольшим количеством чувства открытия, мы могли бы немного узнать, читая Manpage для Pthread_rwlock_unlock, в котором говорится, что это условие undefinised поведение , что является отличным домом. < / P >.

posix устанавливает базу, а не ограничение, поэтому возможно, что ваша реализация может поддерживать такую ​​собственность. I Программируйте, как один выше, является хорошим следственным инструментом; Если он подведет что-то вроде Enotowner; Но Einval будет довольно не примитесь.

Узлы Glic's Rwlock (sysdeps / htl / ​​bits / tyms / struct ___ pthread_rwlock.h):

 <код> struct __pthread_rwlock {   __pthread_spinlock_t __held;   __pthread_spinlock_t __lock;   int __readers;   struct __pthread *__readerqueue;   struct __pthread *__writerqueue;   struct __pthread_rwlockattr *__attr;   void *__data; };   

подтверждает наше подозрение; Сначала я был надеждой, с очередями и всем, но немного погружение через код, раскрыл их, чтобы быть списки ожидания, а не списки владельца.

Вышеуказанное было запущено на Ubuntu 18.04; Linux 4.15.0-11-дюйм; GCC 7.5.0; glibc 2.27 libpthread 2.27.

 

Your good question has a few problems with a complete answer:

  1. It is dependent upon which OS kernel you are running, and possibly even which version.
  2. It is dependent upon which libc/libpthread you are using, and possibly even which compiler.

Presuming you can untangle a specific configuration above, we are looking at two different outcomes: there is a single writer, or a set of readers who currently cause pthread_rw_lock() to block for some callers. In contrast, a mutex has only ever one owner and only that owner can release it.

So a first test in finding out whether your system has a findable owner set is to see if it actually records the ownership. A quick hack to this would be have one thread acquire the rwlock for read or write, then signal a second one to release it. If the release fails, your implementation properly records it, and you have a chance; if not, your implementation likely implements rwlocks with mutex + condvar + counter; so it has no idea of ownership.

So, some code:

#include <stdio.h> #include <pthread.h>  pthread_mutex_t lock; pthread_cond_t cv; pthread_rwlock_t rwl; int ready;  void *rlse(void *_) {     int *t = _;     pthread_mutex_lock(&lock);     while (ready == 0) {         pthread_cond_wait(&cv, &lock);     }     ready = 0;     pthread_cond_signal(&cv);     pthread_mutex_unlock(&lock);     *t = pthread_rwlock_unlock(&rwl);     return 0; }  void *get(void *_) {     int *t = _;     *t = (*t) ? pthread_rwlock_wrlock(&rwl) : pthread_rwlock_rdlock(&rwl);     if (*t == 0) {         pthread_mutex_lock(&lock);         ready = 1;         pthread_cond_signal(&cv);         while (ready == 1) {             pthread_cond_wait(&cv, &lock);         }         pthread_mutex_unlock(&lock);     }     return 0; }  int main() {     pthread_t acq, rel;     int v0, v1;     int i;     for (i = 0; i < 2; i++) {         pthread_rwlock_init(&rwl, 0);         pthread_mutex_init(&lock, 0);         pthread_cond_init(&cv, 0);         v0 = i;         pthread_create(&acq, 0, get, &v0);         pthread_create(&rel, 0, rlse, &v1);         pthread_join(acq, 0);         pthread_join(rel, 0);         printf("%s: %d %d ", i ? "write" : "read", v0, v1);     }     return 0; } 

which we run as:

u18:src $ cc rw.c -lpthread -o rw u18:src $ ./rw read: 0 0 write: 0 0 

This is telling us that in either case (rdlock, wrlock), a thread different from the calling thread can release the rwlock, thus it fundamentally has no owner.

With a little less sense of discovery, we could have found out a bit by reading the manpage for pthread_rwlock_unlock, which states that this condition is undefined behavior, which is the great cop-out.

Posix establishes a base, not a limit, so it is possible your implementation can support this sort of ownership. I program like the one above is a good investigative tool; if it turns up something like ENOTOWNER; but EINVAL would be pretty non-committal.

The innards of glic's rwlock (sysdeps/htl/bits/types/struct___pthread_rwlock.h):

struct __pthread_rwlock {   __pthread_spinlock_t __held;   __pthread_spinlock_t __lock;   int __readers;   struct __pthread *__readerqueue;   struct __pthread *__writerqueue;   struct __pthread_rwlockattr *__attr;   void *__data; }; 

confirms our suspicion; at first I was hopeful, with the queues and all, but a little diving through the code revealed them to be the waiting lists, not the owner lists.

The above was run on ubuntu 18.04; linux 4.15.0-112-generic; gcc 7.5.0; glibc 2.27 libpthread 2.27.

</div
 
 

Связанный проблема

2  Обработка потоков в приложении C # WPF  ( Handling threads in c sharp wpf application ) 
Я делаю приложение C # WPF с Visual Studio 2012. Есть два текстовых ящика с именем TextBoxInput и TextBoxOutput. Моя задача - это когда я печатаю в TextBoxInp...

2  Как сделать переводчик Mod_Perl Sticky по некоторым конвенциям?  ( How to make a mod perl interpreter sticky by some conventions ) 
Как кажется, что mod_perl только удается Perl Переводчики на VHOST Есть любой способ, которым я могу влиять, какой клонированный переводчик MOD_PERL Выбирае...

4  Работает ли агент Java в отдельной нити?  ( Does a java agent run in a separate thread ) 
Я чувствую, что это то, что я должен знать, но делает агент Java (указанный с -javaagent) в отдельной нити? Я прочитал, что java-агент - это библиотека подкл...

8  ID «Главная» нить в C ++  ( Id of main thread in c ) 
Есть ли путь в C ++, чтобы получить идентификатор «основной» поток программы? Я вижу, что <код> std::this_thread::get_id() получает идентификатор текущего ...

0  Как получить доступ к тому же сокету на нескольких потоках для многопоточного клиента  ( How to access same socket on multiple threads for multi threaded client ) 
У меня есть многопоточный клиент, который настроен для получения сообщений на одном потоке с сервера, в то время как другой поток ждет для ввода пользователя,...

96  iPhone iOS работает в отдельной нити  ( Iphone ios running in separate thread ) 
Какой лучший способ запустить код на отдельной ните? Это: <код> [NSThread detachNewThreadSelector: @selector(doStuff) toTarget:self withObject:NULL]; ил...

-1  Распечатать даже и нечетные номера в C #, используя два потока, то есть даже нить и нечетную поток  ( Print even and odd numbers in c sharp using two thread ie even thread and odd th ) 
/ * Мои требования Один поток должен печатать даже номеров, а другой должен печатать нечетные номера. Эти потоки должны распечатать номера по порядку (1, 2, 3...

1  Попытка запуска двух процессов одновременно в GCD - iOS  ( Attempting to run two processes simultaneously in gcd ios ) 
Я пытаюсь загрузить два набора данных на заднем плане одновременно через GCD в iOS. В настоящее время я построил две отдельные одновременные очереди, в которы...

157  Попытался прочитать или писать защищенную память. Это часто является признаком того, что другая память повреждена  ( Attempted to read or write protected memory this is often an indication that ot ) 
Я надеюсь, что кто-то может просветить меня относительно того, что может вызвать эту ошибку: попытался прочитать или писать защищенную память. Это часто яв...

0  Почему я не могу запустить свой метод изнутри hamsters.js?  ( Why cant i run my method from inside hamsters js ) 
Я хочу запустить эту функцию, для обновления моей БД в многопотативном режиме: <код> var params = {'array': array}; hamsters.run(params, function () { ...

0  Как реализовать иерархический замок или другой шаблон синхронизации?  ( How to implement a hierarchical lock or other synchronization pattern ) 
У меня есть серия логически подключенных коллекций объектов A, B и C, которые доступны писательными потоками, потоками только для чтения и потоками чтения. ...

7  Ошибочный pampedlock.unlock (длинное) поведение?  ( Erratic stampedlock unlocklong behaviour ) 
Я сталкиваюсь с странным поведением о Stampedlock / a>. Вот главные проблемные линии кода: <код> StampedLock lock = new StampedLock(); long stamp1 = lock....

6  Singleton & Multi-Threading  ( Singleton multi threading ) 
У меня есть следующий класс <код> class Singleton { private: static Singleton *p_inst; Singleton(); public: static Singleton * instance()...

7  В чем разница в .NET между развитием многопоточного применения и параллельного программирования?  ( What is the difference in net between developing a multithreaded application an ) 
Недавно я много читал о параллельном программировании в .NET, но я все еще путаю в том, чтобы противоречить заявлениям над текстами на эту тему. Например, в...

110  Скала актеры: прием против реагирования  ( Scala actors receive vs react ) 
Позвольте мне сначала сказать, что у меня довольно много явского опыта, но только недавно заинтересовались функциональными языками. Недавно я начал смотреть н...

Связанный проблема

2  Обработка потоков в приложении C # WPF 
2  Как сделать переводчик Mod_Perl Sticky по некоторым конвенциям? 
4  Работает ли агент Java в отдельной нити? 
8  ID «Главная» нить в C ++ 
0  Как получить доступ к тому же сокету на нескольких потоках для многопоточного клиента 
96  iPhone iOS работает в отдельной нити 
-1  Распечатать даже и нечетные номера в C #, используя два потока, то есть даже нить и нечетную поток 
1  Попытка запуска двух процессов одновременно в GCD - iOS 
157  Попытался прочитать или писать защищенную память. Это часто является признаком того, что другая память повреждена 
0  Почему я не могу запустить свой метод изнутри hamsters.js? 
0  Как реализовать иерархический замок или другой шаблон синхронизации? 
7  Ошибочный pampedlock.unlock (длинное) поведение? 
6  Singleton & Multi-Threading 
7  В чем разница в .NET между развитием многопоточного применения и параллельного программирования? 
110  Скала актеры: прием против реагирования