VC ADO 多執行緒高效 安全的讀寫資料庫

2021-07-31 08:00:21 字數 2827 閱讀 8304

專案需要實時獲取並處理40路相機的現場影象,並將處理結果寫入到資料庫,採用的方案是使用多執行緒技術,建立40個工作者執行緒,每個執行緒建立乙個資料庫連線。本文僅將專案中遇到的問題以及解決方法做些記錄。

在單執行緒程式中,只需建立乙個資料庫連線。在多執行緒中,因為多執行緒是並行處理的(對於多核cpu來說),若按單執行緒方式只建立乙個資料庫連線,多執行緒共用此連線,那麼必然存在排隊等待的問題。比較好的方法是每個執行緒建立乙個單獨的連線。

採用ado技術在多執行緒中建立多個資料庫連線時,必須在每個執行緒中使用coinitialize(null)初始化com庫。

執行緒結束時,必須在每個執行緒中使用couninitialize()釋放com資源。

///

//// main.cpp ///

///////

//////

//////

//////

////////

#include "iostream"

#include "atlstr.h"

using namespace std;

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("eof","adoeof")

unsigned int __stdcall threadproc(pvoid);//工作者執行緒函式

int total = 40; //工作者執行緒總數

int index = 0;

void main()

getchar(); // 主線程阻塞在此處

}//工作者執行緒函式

unsigned int __stdcall threadproc(pvoid)

;server=lenovo-pc01;database=dbtest;uid=sa;pwd=mima","","",adconnectunspecified);

}catch(_com_error e)

for (int j = 0 ; j < 100; j++)

if (pconn->state == adstateopen )

::couninitialize();//反初始化com庫

return

0;}

當執行緒數一多,使用上述**百分百會出現問題,提示如下: 

原因在於資料庫建立連線是個非常消耗資源與時間的工作,同時建立大量連線,完成這些連線的耗時必將非常長,而資料庫預設的連線超時為30s,一旦超過這個時間,程式就會傳回超時錯誤。解決方法如下:

將連線超時調大,大到足夠完成所有連線的建立。

連線排隊建立,只有上個連線建立完成,才開始建立下乙個連線,直至所有連線建立完成。

方案1:

//設定超時時間足夠大,此處為3000s

pconn->connectiontimeout =

3000; //設定連線超時時間 3000s

方案2,推薦採用,實現**如下:

///

//// main.cpp ///

///////

//////

//////

//////

////////

#include "iostream"

#include "atlstr.h"

using namespace std;

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("eof","adoeof")

unsigned int __stdcall threadproc(pvoid);//工作者執行緒函式

int total = 40;//工作者執行緒總數

int index = 0;

int *flag = new

int[total](); // 連線建立成功標誌

void main()

int f = flag[4];

resumethread(hthread[0]);

for (int i = 1; i < total ; i++)

resumethread(hthread[i]);

}getchar();

delete hthread;

delete flag;

}unsigned int __stdcall threadproc(pvoid)

;server=lenovo-pc01;database=huayutest;uid=sa;pwd=mima","","",adconnectunspecified);

}catch(_com_error e)

cout << "connect:"

<1; //

index++;

for (int j = 0 ; j < 100; j++)

if (pconn->state == adstateopen )

::couninitialize();//反初始化com庫

return

0;}

多執行緒併發訪問資料庫,解決方法是在每個執行緒中建立乙個資料庫連線,需要注意的兩點如下:

必須在每個執行緒中都呼叫coinitialize(null)和couninitialize()來初始化com庫和釋放com庫資源。

同時建立多個資料庫連線時,需要注意資料庫連線超時問題,解決方法是分批建立資料庫連線。

**:

執行緒安全讀取mysql 多執行緒讀寫mysql資料庫

該樓層疑似違規已被系統摺疊 隱藏此樓檢視此樓 unsigned int stdcall scan pvoid pm char ip 20 strcpy ip,char pm mysql mysql mysql res result 初始化mysql控制代碼 mysql init mysql 連線my...

多執行緒讀寫mysql 多執行緒讀寫mysql資料庫

該樓層疑似違規已被系統摺疊 隱藏此樓檢視此樓 unsigned int stdcall scan pvoid pm char ip 20 strcpy ip,char pm mysql mysql mysql res result 初始化mysql控制代碼 mysql init mysql 連線my...

(多執行緒)多執行緒的併發安全

多執行緒併發操作同乙個資源 同步鎖 多執行緒操作的鎖必須唯一 必須搞清楚 哪些 需要同步?那些在操作共享資源的 只要包含非讀的操作,或者根據共享資源進行條件判斷的,就需要同步!同步 塊解決 package com.gc.thread 多執行緒操作共享資源 併發 執行緒安全問題 同步 鎖 相對而言效能...