-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rwlock deadlock, Rwlock::unlock cross thread unlock not work #5024
Comments
因为Swoole lock设计上是用来实现进程同步的,底层采用的是共享内存,所以只要一个子进程没解锁,剩下的子进程都得阻塞。 |
你应该查看一下代码再说,我是说读写锁在跨进程解锁存在bug,因为swoole-cli的单文件是不存在这个问题的,这个bug只存在于读写锁且属于普通php模式下pecl库安装的swoole才会触发 |
好的,我再测试看看😁。 |
我顺便补充了一下在我本机测试的输出结果,就那串代码,你用swoole-cli和php-cli分别运行一次就知道了,还有很奇怪这个bug只有读写锁会,互斥之类的锁都不会,我也是在自动化覆盖测试卡住才发现的 |
好的,谢谢 |
怀疑是 glibc pthread 的 BUG,暂时无法解决。swoole-cli 使用的是 Musl libc ,不存在此问题。需要向 glibc 官方求助了 |
韩大佬出现了,我还以为这个bug没人管了呢,我倒是用不上读写锁,只是发现了这个问题反馈了一下,这种奇怪的问题估计上游也不怎么可能快速修复,我c比较捉急,所以这事韩大佬看着来吧 |
已经代码精简为一个
代码如下:#include <iostream>
#include <pthread.h>
#include <thread>
#include <unistd.h>
struct RWLockImpl {
pthread_rwlock_t _lock;
pthread_rwlockattr_t attr;
RWLockImpl() {
pthread_rwlockattr_init(&attr);
if (pthread_rwlock_init(&_lock, &attr) != 0) {
throw std::system_error(errno, std::generic_category(),
"pthread_rwlock_init() failed");
}
}
int lock() { return pthread_rwlock_wrlock(&_lock); }
int unlock() { return pthread_rwlock_unlock(&_lock); }
};
struct MutexImpl {
pthread_mutex_t lock_;
pthread_mutexattr_t attr_;
MutexImpl() {
pthread_mutexattr_init(&attr_);
if (pthread_mutex_init(&lock_, &attr_) != 0) {
throw std::system_error(errno, std::generic_category(),
"pthread_mutex_init() failed");
}
}
int lock() { return pthread_mutex_lock(&lock_); }
int unlock() { return pthread_mutex_unlock(&lock_); }
};
int main(int argc, char **argv) {
RWLockImpl impl;
// MutexImpl impl;
std::thread threads[5];
for (int i = 0; i < 5; i++) {
threads[i] = std::thread([&impl, i]() {
if (i == 3) {
sleep(3);
std::cout << i << " try unlock, result=" << impl.unlock() << std::endl;
}
std::cout << i << " try lock " << std::endl;
if (impl.lock() == 0) {
sleep(1);
std::cout << i << " lock success " << std::endl;
}
if (i == 0) {
std::cout << i << " no unlock, exit directly " << std::endl;
pthread_exit(0);
return;
}
std::cout << i << "lock close, result=" << impl.unlock() << std::endl;
pthread_exit(0);
return;
});
}
for (int i = 0; i < 5; i++) {
threads[i].join();
}
} 编译g++ rwlock.cpp -pthread -std=c++11 -g -o rwlock 使用 RWLock 时./rwlock
0 try lock
2 try lock
1 try lock
4 try lock
0 lock success
0 no unlock, exit directly
3 try unlock, result=0
3 try lock
^C
swoole@swoole-ThinkPad-T470p:~/workspace/debug$ 改为 Mutexswoole@swoole-ThinkPad-T470p:~/workspace/debug$ ./rwlock
0 try lock
1 try lock
24 try lock try lock
0 lock success
0 no unlock, exit directly
3 try unlock, result=0
3 try lock
3 lock success
3lock close, result=0
4 lock success
4lock close, result=0
2 lock success
2lock close, result=0
1 lock success
1lock close, result=0
swoole@swoole-ThinkPad-T470p:~/workspace/debug$ 总结在线程0 中 lock() 成功,但未解锁直接退出,另外一个线程 |
Tps:
php --ri swoole
)?uname -a
&php -v
&gcc -v
) ?The text was updated successfully, but these errors were encountered: