diff --git a/LibManageSystem_Server/mythread.cpp b/LibManageSystem_Server/mythread.cpp index c47ca92b657714a70f58559f347d4206abc15c7b..fc9eb18f9cf68575d40a3073045019e921a43cbb 100644 --- a/LibManageSystem_Server/mythread.cpp +++ b/LibManageSystem_Server/mythread.cpp @@ -1,16 +1,16 @@ #include "mythread.h" -MyThread::MyThread(int curThreadHandle,QMutex* network_send_locker,QObject *parent) +MyThread::MyThread(int curThreadHandle,QMutex* network_send_locker,QMutex* db_add_locker,QMutex* pic_add_locker,QObject *parent) : QObject{parent},socket(nullptr),threadHandle(curThreadHandle),sentsize(0), - totalsize(0),msec300_pluse_timer(nullptr),mutex_msg_locker(network_send_locker),MemoryApplicationFailCount(0) + totalsize(0),msec300_pluse_timer(nullptr),mutex_msg_locker(network_send_locker), + mutex_dbDat_locker(db_add_locker),mutex_picDat_locker(pic_add_locker),network_lock_here(false), + dbDat_addition_lock_here(false),picDat_addition_lock_here(false),MemoryApplicationFailCount(0) { } MyThread::~MyThread() { - if(lock_here&&!mutex_msg_locker->tryLock()) - mutex_msg_locker->unlock(); resetThreadState(); } @@ -56,8 +56,18 @@ void MyThread::resetThreadState() disconnect(socket,&QTcpSocket::readyRead,this,&MyThread::PreProcessClientData); socket->deleteLater(); socket=nullptr; - if(lock_here&&!mutex_msg_locker->tryLock()) - mutex_msg_locker->unlock(); + } + if(network_lock_here){ + mutex_msg_locker->unlock(); + network_lock_here=false; + } + if(dbDat_addition_lock_here){ + mutex_dbDat_locker->unlock(); + dbDat_addition_lock_here=false; + } + if(picDat_addition_lock_here){ + mutex_picDat_locker->unlock(); + picDat_addition_lock_here=false; } if(sec10_pluse_timer!=nullptr){ disconnect(sec10_pluse_timer,&QTimer::timeout,this,&MyThread::resetThreadState); @@ -141,6 +151,11 @@ void MyThread::addDataBaseData(int threadhandle) { if(threadhandle==threadHandle) { + mutex_dbDat_locker->lock(); + //成功上锁 + dbDat_addition_lock_here=true; + emit apply_for_db_addition_locker(threadHandle); + qsizetype i,booksize; QVector::Iterator ptr=received_books_dat->begin(); msg_tobe_sent.clear(); @@ -241,6 +256,9 @@ void MyThread::addDataBaseData(int threadhandle) received_books_dat=nullptr; received_user_dat=nullptr; emit update_progress(threadHandle,40); + //解锁 + mutex_dbDat_locker->unlock(); + dbDat_addition_lock_here=false; totalsize=msg_tobe_sent.size(); sentsize=0; @@ -266,11 +284,18 @@ void MyThread::addPicData(int threadhandle) { if(threadhandle==threadHandle) { + mutex_picDat_locker->lock(); + //成功上锁 + picDat_addition_lock_here=true; + emit apply_for_pic_addition_locker(threadHandle); msg_tobe_sent+="IMAGEG" + picCaptureTag.toStdString() + stopChar; msg_tobe_sent+=*received_pic_dat; //数据读取完成后指针悬空 received_pic_dat=nullptr; emit update_progress(threadHandle,40); + //解锁 + mutex_picDat_locker->unlock(); + picDat_addition_lock_here=false; totalsize=msg_tobe_sent.size(); sentsize=0; @@ -564,7 +589,7 @@ void MyThread::FirstTransfer() sec10_pluse_timer->start(10000); mutex_msg_locker->lock(); //成功上锁 - lock_here=true; + network_lock_here=true; emit apply_for_network_locker(threadHandle); QByteArray first_transfer_header; @@ -592,7 +617,7 @@ void MyThread::FirstTransfer() //解锁 mutex_msg_locker->unlock(); - lock_here=false; + network_lock_here=false; } void MyThread::ContinueTransfer() @@ -601,7 +626,7 @@ void MyThread::ContinueTransfer() sec10_pluse_timer->start(10000); mutex_msg_locker->lock(); //成功上锁 - lock_here=true; + network_lock_here=true; emit apply_for_network_locker(threadHandle); QByteArray transfer_header; @@ -629,7 +654,7 @@ void MyThread::ContinueTransfer() //解锁 mutex_msg_locker->unlock(); - lock_here=false; + network_lock_here=false; if(sentsize==totalsize){ //所有数据都已发送完毕 diff --git a/LibManageSystem_Server/mythread.h b/LibManageSystem_Server/mythread.h index d9c6b1c8eada474a97b32a69524b7936b19ab219..f7bc066abcb47883bd62cb955982f11a0297d8ef 100644 --- a/LibManageSystem_Server/mythread.h +++ b/LibManageSystem_Server/mythread.h @@ -16,7 +16,7 @@ class MyThread : public QObject Q_OBJECT public: //ThreadHandle为本线程编号 - explicit MyThread(int ThreadHandle,QMutex* network_send_locker,QObject *parent = nullptr); + explicit MyThread(int ThreadHandle,QMutex* network_send_locker,QMutex* db_add_locker,QMutex* pic_add_locker,QObject *parent = nullptr); ~MyThread(); signals: //套接字尝试连接失败 @@ -31,6 +31,10 @@ signals: void readyForSend(); //申请网络通信锁成功时发出信号 void apply_for_network_locker(int threadhandle); + //申请装载数据库资源锁成功时发出信号 + void apply_for_db_addition_locker(int threadhandle); + //申请装载图片资源锁成功时发出信号 + void apply_for_pic_addition_locker(int threadhandle); //更新处理进度 void update_progress(int threadhandle,int percentage); //本次任务完成 @@ -77,10 +81,10 @@ private: qsizetype sentsize,totalsize; //msec300_pluse_timer为每300毫秒单次触发计时器,sec10_pluse_timer为每10秒单次触发计时器,用于防止线程卡死状态 QTimer* msec300_pluse_timer,*sec10_pluse_timer; - //通信锁,减少资源竞争 - QMutex* mutex_msg_locker; - //用于记录通信锁是否在本线程手中 - bool lock_here; + //线程锁,减少资源竞争 + QMutex *mutex_msg_locker,*mutex_dbDat_locker,*mutex_picDat_locker; + //用于锁是否在本线程手中 + bool network_lock_here,dbDat_addition_lock_here,picDat_addition_lock_here; //用于记录是否已分配内存 bool isMemoryDistributed; //用于记录申请内存分配失败的次数 diff --git a/LibManageSystem_Server/tcpserver.cpp b/LibManageSystem_Server/tcpserver.cpp index 614179222ca04a9a8d79aea4780d78a8e7786959..ac559c3e5ea58b30e3569c78d0700ce96b86b7c5 100644 --- a/LibManageSystem_Server/tcpserver.cpp +++ b/LibManageSystem_Server/tcpserver.cpp @@ -1,7 +1,8 @@ #include "tcpserver.h" TcpServer::TcpServer(Operat* DataBase,QString Resources_Path,QObject *parent) - : QTcpServer{parent},threadcount(0),resources_path(Resources_Path),locker_occupancy(0),dataBase(DataBase) + : QTcpServer{parent},threadcount(0),resources_path(Resources_Path),network_locker_occupancy(-1), + db_data_locker_occupancy(-1),pic_data_locker_occupancy(-1),dataBase(DataBase) { //获取最佳线程数,重设分配的空间 int idealThreadNumbers=QThread::idealThreadCount(); @@ -19,6 +20,8 @@ TcpServer::TcpServer(Operat* DataBase,QString Resources_Path,QObject *parent) sec1_timer=new QTimer(this); msec500_pluse_timer=new QTimer(this); network_locker=new QMutex; + db_data_addition_locker=new QMutex; + pic_data_addition_locker=new QMutex; //设置单次触发,在访问周期结束后再重启 msec500_pluse_timer->setSingleShot(true); sec1_timer->start(1000); @@ -61,6 +64,8 @@ void TcpServer::deleteUnusedThread() disconnect(workerlist[i],&MyThread::apply_for_db,this,&TcpServer::db_application); disconnect(workerlist[i],&MyThread::apply_for_pic,this,&TcpServer::pic_application); disconnect(workerlist[i],&MyThread::apply_for_network_locker,this,&TcpServer::network_application); + disconnect(workerlist[i],&MyThread::apply_for_db_addition_locker,this,&TcpServer::dbDat_addition_application); + disconnect(workerlist[i],&MyThread::apply_for_pic_addition_locker,this,&TcpServer::picDat_addition_application); disconnect(workerlist[i],&MyThread::work_finished,this,&TcpServer::free_thread); disconnect(this,&TcpServer::dataBaseOperationSuccess,workerlist[i],&MyThread::addDataBaseData); disconnect(this,&TcpServer::dataBaseOperationFail,workerlist[i],&MyThread::addDataBaseError); @@ -130,7 +135,7 @@ void TcpServer::processNewConnection() if(threadstate[i]==0||threadstate[i]==3){ //有未创建或者已销毁的线程空位,创建新线程以及工作类型 QThread *newThread=new QThread; - MyThread *worker=new MyThread(i,network_locker); + MyThread *worker=new MyThread(i,network_locker,db_data_addition_locker,pic_data_addition_locker); worker->moveToThread(newThread); //关联设置套接字的信号与处理槽函数 @@ -149,6 +154,10 @@ void TcpServer::processNewConnection() connect(worker,&MyThread::apply_for_pic,this,&TcpServer::pic_application,Qt::QueuedConnection); //关联线程占用网络通信资源信号 connect(worker,&MyThread::apply_for_network_locker,this,&TcpServer::network_application,Qt::QueuedConnection); + //关联线程装载数据库资源信号 + connect(worker,&MyThread::apply_for_db_addition_locker,this,&TcpServer::dbDat_addition_application,Qt::QueuedConnection); + //关联线程装载图片资源信号 + connect(worker,&MyThread::apply_for_pic_addition_locker,this,&TcpServer::picDat_addition_application,Qt::QueuedConnection); //关联线程工作完成与线程空闲处理槽函数 connect(worker,&MyThread::work_finished,this,&TcpServer::free_thread,Qt::QueuedConnection); //关联数据库操作成功信号与子线程添加数据槽函数 @@ -422,7 +431,17 @@ void TcpServer::visitPicture(int threadhandle) void TcpServer::network_application(int threadhandle) { - locker_occupancy=threadhandle; + network_locker_occupancy=threadhandle; +} + +void TcpServer::dbDat_addition_application(int threadhandle) +{ + db_data_locker_occupancy=threadhandle; +} + +void TcpServer::picDat_addition_application(int threadhandle) +{ + pic_data_locker_occupancy=threadhandle; } void TcpServer::free_thread(int threadhandle) @@ -453,6 +472,31 @@ void TcpServer::free_thread(int threadhandle) pictures[i].second=-1; pictures[i].first.clear(); } + //若该线程在占用线程锁,则释放锁 + if(!network_locker->tryLock(0)){ + if(threadhandle==network_locker_occupancy){ + network_locker_occupancy=-1; + network_locker->unlock(); + } + } + else + network_locker->unlock(); + if(!db_data_addition_locker->tryLock(0)){ + if(threadhandle==db_data_locker_occupancy){ + db_data_locker_occupancy=-1; + db_data_addition_locker->unlock(); + } + } + else + db_data_addition_locker->unlock(); + if(!pic_data_addition_locker->tryLock(0)){ + if(threadhandle==pic_data_locker_occupancy){ + pic_data_locker_occupancy=0; + pic_data_addition_locker->unlock(); + } + } + else + pic_data_addition_locker->unlock(); //有空闲的线程则开始处理下一个客户端连接 emit ThreadIsFree(threadhandle); processNewConnection(); @@ -473,4 +517,6 @@ TcpServer::~TcpServer() } } delete network_locker; + delete db_data_addition_locker; + delete pic_data_addition_locker; } diff --git a/LibManageSystem_Server/tcpserver.h b/LibManageSystem_Server/tcpserver.h index 0dfba21dc0dbc1d6b7fe4640ea790db0aa9e7ad3..eac197dcc9e8871869622692ccd23565d67b330a 100644 --- a/LibManageSystem_Server/tcpserver.h +++ b/LibManageSystem_Server/tcpserver.h @@ -66,6 +66,10 @@ private slots: void process_application(); //用于记录已经获得网络通信锁的线程句柄 void network_application(int threadhandle); + //用于记录已经获得装载数据库资源锁的线程句柄 + void dbDat_addition_application(int threadhandle); + //用于记录已经获得装载图片资源锁的线程句柄 + void picDat_addition_application(int threadhandle); //将线程状态转为空闲并释放分配给线程的数据库内存和图片内存 void free_thread(int threadhandle); //将空闲时间到达10s的线程销毁 @@ -99,9 +103,13 @@ private: //图片资源文件路径 QString resources_path; //网络通信锁,用于限制同时只能有一个线程在发送数据 - QMutex* network_locker; + QMutex *network_locker; //用于记录当前占用着网络通信锁的线程句柄 - int locker_occupancy; + int network_locker_occupancy; + //资源锁,用于限制同时只能有一个线程在装载数据 + QMutex *db_data_addition_locker,*pic_data_addition_locker; + //用于记录当前占用着资源锁的线程句柄 + int db_data_locker_occupancy,pic_data_locker_occupancy; //db_data存放从数据库获取的信息,第二个为线程句柄以及处理类型,线程句柄没有线程占用时默认为-1 vector,User>,int>> db_data;