实验操作流程
先使用su
命令将用户切换为root用户,
将threadpool.cpp 和 threadpool.h编译成动态库
jyhlinux@ubuntu:~/share/threadpool$ g++ -fPIC -shared threadpool.cpp -o libtdpool.so -std=c++17
将生成的库和头文件放到系统目录下,并将源文件删除
root@ubuntu:/home/jyhlinux/share/threadpool# mv libtdpool.so /usr/local/lib/
root@ubuntu:/home/jyhlinux/share/threadpool# ls
test_threadpool.cpp threadpool.cpp threadpool.h
root@ubuntu:/home/jyhlinux/share/threadpool# rm threadpool.cpp
root@ubuntu:/home/jyhlinux/share/threadpool# mv threadpool.h /usr/local/include/
编译链接生成源文件
root@ubuntu:/home/jyhlinux/share/threadpool# g++ test_threadpool.cpp -std=c++17 -ltdpool -lpthread
执行可执行程序但是失败,因为运行时系统寻找动态库位置有所不同
运行时系统是在/etc/ld.so.cache
文件查找动态库链接
做以下操作添加配置
root@ubuntu:/etc/ld.so.conf.d# vim /etc/ld.so.conf
添加一行 /usr/local/lib
紧接着回到测试文件路径,刷新动态库配置
jyhlinux@ubuntu:/etc/ld.so.conf.d$ cd ~/share/threadpool
jyhlinux@ubuntu:~/share/threadpool$ sudo ldconfig
再次执行程序,程序正常运行,乱码是编码问题
一些问题
问题描述
如果是老版本的g++,则可能会出现死锁的现象,是由于g++下condition_variable
析构不做任何事,导致Semaphore
类中notify
也会阻塞:
void post()
{
std::unique_lock<std::mutex> lock(mtx_);
resLimit_++;
cond_.notify_all(); // 阻塞在这里!!!
}
可以使用gdb调试线程
gdb attach 进程号 #调试进程
info threads #查看进程中所有线程,前面有*代表当前线程
thread id #切换到info threads查看的线程id
bt #查看线程调用堆栈
解决办法
可以在Semaphore
类里添加一个bool
值标识是否已经退出,若退出就不要做加锁和 wait
以及 notify
操作,修改后的Semaphore
类为
class Semaphore
{
public:
Semaphore(int limit = 0)
:resLimit_(limit)
{
}
~Semaphore()
{
isExit_ = true;
}
void wait()
{
if(isExit_) return ; //
std::unique_lock<std::mutex> lock(mtx_);
cond_.wait(lock, [&]()->bool {
return resLimit_ > 0; }); //
resLimit_--;
}
void post()
{
if(isExit_) return ;//
std::unique_lock<std::mutex> lock(mtx_);
resLimit_++;
cond_.notify_all();
}
private:
std::atomic_bool isExit_;//
int resLimit_;
std::mutex mtx_;
std::condition_variable cond_;
};