У меня есть два дня, чтобы исследовать связанные с записью-записью блокировки. И я столкнулся с проблемой из-за ограничения виртуальной нити GCD: Dead Lock With `dispatch_barrier`Странный тупик с функцией `static` или нет
Затем я попытаюсь использовать pthread_rwlock_t
для реализации rwlock. Он работает нормально, как конец статьи.
Но, когда я хочу, чтобы переместить код инициализации pthread_rwlock_t
в static
функции, как код ниже, я нашел, что это ввести затор снова.
После этого я думаю, что долгое время и отладки, я нахожу странную вещь: Когда я выхожу из кода инициализации (также содержит dispatch_once
) от static
функции. Все в порядке. это так странно, и я думаю, что это не из-за ограничения виртуального потока GCD. @ Originaluser2
#import <pthread.h>
#define THREAD_ASSERT_ON_ERROR(x_) do { \
_Pragma("clang diagnostic push"); \
_Pragma("clang diagnostic ignored \"-Wunused-variable\""); \
volatile int res = (x_); \
assert(res == 0); \
_Pragma("clang diagnostic pop"); \
} while (0)
static pthread_rwlock_t kRWLock(){
static pthread_rwlock_t _rwlock;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
THREAD_ASSERT_ON_ERROR(pthread_rwlock_init(&_rwlock, NULL));
});
return _rwlock;
}
//#define WILLDEADLOCK //define it will see the deadlock demo
- (void)test
{
dispatch_queue_t queue = dispatch_queue_create("com.test.testasync", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i=0; i<5000; i++) {
dispatch_async(queue, ^{
#ifdef WILLDEADLOCK
pthread_rwlock_t rwlock = kRWLock();
#else
static pthread_rwlock_t rwlock;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
THREAD_ASSERT_ON_ERROR(pthread_rwlock_init(&rwlock, NULL));
});
#endif
THREAD_ASSERT_ON_ERROR(pthread_rwlock_rdlock(&rwlock));
NSLog(@"rlock1");
NSLog(@"runlock1");
THREAD_ASSERT_ON_ERROR(pthread_rwlock_unlock(&rwlock));
if (i%100==0) {
THREAD_ASSERT_ON_ERROR(pthread_rwlock_wrlock(&rwlock));
NSLog(@"wlock1");
NSLog(@"wunlock1");
THREAD_ASSERT_ON_ERROR(pthread_rwlock_unlock(&rwlock));
}
});
}
dispatch_barrier_sync(queue, ^{});
NSLog(@"completed");
}
Когда вы отвечаете на свой вопрос здесь, введите его в качестве фактического ответа. Через пару дней вы можете «принять» свой ответ, чтобы люди знали, что он решен. – Almo
@Almo Извините, я не был уполномочен писать ответы по некоторым причинам .. поэтому я должен обновить ответ в сообщении. – molon
Хорошо, я отправлю его в качестве ответа для вас. :) – Almo