新聞中心
在現(xiàn)代計(jì)算機(jī)系統(tǒng)中,數(shù)據(jù)庫(kù)是維護(hù)數(shù)據(jù)的主要工具。由于實(shí)際工作中可能有多個(gè)用戶需要同時(shí)訪問(wèn)數(shù)據(jù)庫(kù),因此實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)是非常必要的。在本文中,我們將介紹如何使用 C 編程語(yǔ)言實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)的方法。

1. 數(shù)據(jù)庫(kù)和并發(fā)
在了解如何實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)之前,我們首先需要了解數(shù)據(jù)庫(kù)和并發(fā)之間的關(guān)系。具體來(lái)說(shuō),一個(gè)數(shù)據(jù)庫(kù)是一個(gè)存儲(chǔ)和管理數(shù)據(jù)的系統(tǒng),它需要支持多個(gè)用戶同時(shí)訪問(wèn)和操作數(shù)據(jù)。在這種情況下,我們稱這些操作為并發(fā)操作。在并發(fā)操作中,我們需要確保多個(gè)用戶操作之間的數(shù)據(jù)一致性和完整性,以避免出現(xiàn)數(shù)據(jù)沖突和錯(cuò)誤。
2. 并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)的方法
為了實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù),我們需要考慮以下幾個(gè)方面:
2.1. 數(shù)據(jù)庫(kù)連接
在使用 C 實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)之前,我們需要確保已經(jīng)建立了數(shù)據(jù)庫(kù)連接。一旦有多個(gè)用戶同時(shí)訪問(wèn)數(shù)據(jù)庫(kù),這些用戶將共享同一個(gè)數(shù)據(jù)庫(kù)連接。因此,我們需要確保每個(gè)用戶獲得的都是一個(gè)獨(dú)立的數(shù)據(jù)庫(kù)連接,并且這些連接之間不會(huì)相互干擾。
2.2. 數(shù)據(jù)庫(kù)操作
在多個(gè)用戶同時(shí)訪問(wèn)數(shù)據(jù)庫(kù)時(shí),每個(gè)用戶將執(zhí)行自己的數(shù)據(jù)庫(kù)操作。在這種情況下,我們需要確保每個(gè)用戶執(zhí)行的數(shù)據(jù)庫(kù)操作是正確的,并且不會(huì)影響其他用戶的操作。為此,我們可以使用鎖定機(jī)制(mutex)或事務(wù)(transaction)來(lái)確保數(shù)據(jù)庫(kù)的正確性和完整性。
2.3. 線程
當(dāng)我們使用 C 實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)時(shí),我們通常會(huì)使用線程來(lái)實(shí)現(xiàn)并發(fā)操作。在這種情況下,我們需要確保每個(gè)線程都能夠獨(dú)立運(yùn)行,并且它們之間不會(huì)相互干擾。為了避免競(jìng)爭(zhēng)條件和錯(cuò)誤,我們可以使用線程同步機(jī)制,如互斥鎖(mutex)和條件變量(condition variable),來(lái)確保線程之間的正確的序列和順序執(zhí)行。
3. 使用 C 實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)的示例
下面是一個(gè)使用 C 實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)的簡(jiǎn)單示例。
3.1. 數(shù)據(jù)庫(kù)連接
我們可以使用以下代碼片段來(lái)建立一個(gè)數(shù)據(jù)庫(kù)連接:
“`c
#include
#include
#include
// 定義數(shù)據(jù)庫(kù)連接
sqlite3 *db;
// 建立數(shù)據(jù)庫(kù)連接
int open_database(const char *filename) {
int rc = sqlite3_open(filename, &db);
if (rc != SQLITE_OK) {
fprintf(stderr, “無(wú)法打開數(shù)據(jù)庫(kù): %s\n”, sqlite3_errmsg(db));
sqlite3_close(db);
return rc;
}
return SQLITE_OK;
}
“`
3.2. 數(shù)據(jù)庫(kù)操作
在多個(gè)用戶同時(shí)訪問(wèn)數(shù)據(jù)庫(kù)時(shí),我們需要確保每個(gè)用戶執(zhí)行的數(shù)據(jù)庫(kù)操作是正確的,并且不會(huì)影響其他用戶的操作。下面是一個(gè)使用事務(wù)來(lái)實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)的示例:
“`c
// 開始事務(wù)
sqlite3_exec(db, “BEGIN;”, NULL, NULL, NULL);
// 執(zhí)行數(shù)據(jù)庫(kù)操作
int rc = sqlite3_exec(db, “UPDATE table SET column1 = value1 WHERE id = 1;”, NULL, NULL, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, “執(zhí)行數(shù)據(jù)庫(kù)操作出錯(cuò): %s\n”, sqlite3_errmsg(db));
sqlite3_exec(db, “ROLLBACK;”, NULL, NULL, NULL);
return rc;
}
// 提交事務(wù)
sqlite3_exec(db, “COMMIT;”, NULL, NULL, NULL);
“`
3.3. 線程
當(dāng)我們使用 C 實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)時(shí),我們通常會(huì)使用線程來(lái)實(shí)現(xiàn)并發(fā)操作。下面是一個(gè)使用線程實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)的示例:
“`c
#include
#include
#include
#include
// 定義數(shù)據(jù)庫(kù)連接
sqlite3 *db;
// 建立數(shù)據(jù)庫(kù)連接
int open_database(const char *filename) {
int rc = sqlite3_open(filename, &db);
if (rc != SQLITE_OK) {
fprintf(stderr, “無(wú)法打開數(shù)據(jù)庫(kù): %s\n”, sqlite3_errmsg(db));
sqlite3_close(db);
return rc;
}
return SQLITE_OK;
}
// 線程函數(shù)
void *thread_function(void *arg) {
// 開始事務(wù)
sqlite3_exec(db, “BEGIN;”, NULL, NULL, NULL);
// 執(zhí)行數(shù)據(jù)庫(kù)操作
int rc = sqlite3_exec(db, “UPDATE table SET column1 = value1 WHERE id = 1;”, NULL, NULL, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, “執(zhí)行數(shù)據(jù)庫(kù)操作出錯(cuò): %s\n”, sqlite3_errmsg(db));
sqlite3_exec(db, “ROLLBACK;”, NULL, NULL, NULL);
return (void *)rc;
}
// 提交事務(wù)
sqlite3_exec(db, “COMMIT;”, NULL, NULL, NULL);
return (void *)rc;
}
int mn() {
// 建立數(shù)據(jù)庫(kù)連接
open_database(“test.db”);
// 創(chuàng)建線程
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_function, NULL);
// 等待線程完成
pthread_join(thread_id, NULL);
// 關(guān)閉數(shù)據(jù)庫(kù)連接
sqlite3_close(db);
return 0;
}
“`
4.
相關(guān)問(wèn)題拓展閱讀:
- 大型網(wǎng)站數(shù)據(jù)庫(kù)系統(tǒng),怎么連接那么多并發(fā)數(shù)量的?
- 怎樣在C語(yǔ)言中編寫多個(gè)程序并發(fā)執(zhí)行的程序
大型網(wǎng)站數(shù)據(jù)庫(kù)系統(tǒng),怎么連接那么多并發(fā)數(shù)量的?
現(xiàn)象
Syench對(duì)MySQL進(jìn)行壓測(cè), 并發(fā)數(shù)過(guò)大(>5k)時(shí), Syench建立連接的步驟會(huì)超時(shí).
猜想
猜想: 直覺(jué)上這很簡(jiǎn)單, Syench每建立一個(gè)連接, 都要消耗一個(gè)線程, 資源消耗過(guò)大導(dǎo)致超時(shí).
驗(yàn)證: 修改Syench源碼, 調(diào)大超時(shí)時(shí)間, 仍然會(huì)發(fā)生超時(shí).
檢查環(huán)境
猜想失敗, 回到常規(guī)的環(huán)境檢查:
MySQL error log 未見異常.
syslog 未見異常.
tcpdump 觀察網(wǎng)絡(luò)包未見異常, 連接能完成正常的三次握手; 只觀察到在出問(wèn)題的連接中, 有一部分的TCP握手的之一個(gè)SYN包發(fā)生了重傳, 另一梁轎迅部分沒(méi)有發(fā)生重傳.
自己寫一個(gè)簡(jiǎn)單的并發(fā)發(fā)生器, 替換syench, 可重現(xiàn)場(chǎng)景. 排除syench的影響
猜想2
懷疑 MySQL 在應(yīng)用層因?yàn)槟撤N原因, 沒(méi)有發(fā)送握手包, 比如卡在某一個(gè)流程上:
檢查MySQL堆棧未見異常, 仿佛MySQL在應(yīng)用層沒(méi)有看到新連接進(jìn)入.
通過(guò)strace檢查MySQL, 發(fā)現(xiàn) accept() 調(diào)用確實(shí)沒(méi)有感知到新連接.
懷疑是OS的原因, Google之, 得到參考文檔: A TCP “stuck” connection mystery【
分析
參考文檔中的現(xiàn)象跟目前的狀況很類似, 簡(jiǎn)述如下:
正常的TCP連接流程:
Client 向 Server 發(fā)起連接請(qǐng)求, 發(fā)送SYN.
Server 預(yù)留連接資源, 向 Client 回復(fù)SYN-ACK.
Client 向 Server 回復(fù)ACK.
Server 收到 ACK, 連接建立.
在業(yè)務(wù)層上, Client和Server間進(jìn)行通訊.
當(dāng)發(fā)生類似SYN-flood的現(xiàn)象時(shí), TCP連接的流程會(huì)使用SYN-cookie, 變?yōu)?
Client 向 Server 發(fā)起連接請(qǐng)求, 發(fā)送SYN.
Server 不預(yù)留連接資源, 向 Client 回復(fù)SYN-ACK, 包中附帶有帆陪簽名A.
Client 向 Server 回復(fù)ACK, 附帶 f(簽名A) (對(duì)簽名進(jìn)行運(yùn)算的結(jié)果).
Server 驗(yàn)證簽名, 分配連接資源, 連接建立.
在業(yè)務(wù)層上, Client和Server間進(jìn)行通訊.
當(dāng)啟用SYN-cookie時(shí), 第3步的ACK包因?yàn)?nbsp;某種原因 丟失, 那么:
從Client的視角, 連接已經(jīng)建立.
從Server的視角, 連接并不存在, 既沒(méi)有建立, 也沒(méi)有”即將建立” (若不啟用SYN-cookie, Server會(huì)知道某個(gè)連接”即將建立”)
發(fā)生這種情況時(shí):
若業(yè)務(wù)層的之一個(gè)包應(yīng)是從 Client 發(fā)往 Server, 則會(huì)進(jìn)行重發(fā)或拋出連接錯(cuò)誤
若業(yè)務(wù)層的之一個(gè)包應(yīng)是從 Server 發(fā)往 Client的, Server不會(huì)發(fā)出之一個(gè)包. MySQL的故障就屬于這種情況.
TCP握手的第三步ACK包為什么丟失
參考文檔中, 對(duì)于TCP握手的第三橡此步ACK包的丟失原因, 描述為:
Some of these packets get lost because some buffer somewhere overflows.
我們可以通過(guò)Systemtap進(jìn)一步探究原因. 通過(guò)一個(gè)簡(jiǎn)單的腳本:
probe kernel.function(“cookie_v4_check”).return
{
source_port = @cast($skb->head + $skb->transport_header, “struct tcphdr”)->source
printf(“source=%d, return=%d\n”,readable_port(source_port), $return)
}
function readable_port(port) {
return (port & ((1> 8)
}
觀察結(jié)果, 可以確認(rèn)cookie_v4_check (syn cookie機(jī)制進(jìn)行包簽名檢查的函數(shù))會(huì)返回 NULL(0). 即驗(yàn)證是由于syn cookie驗(yàn)證不通過(guò), 導(dǎo)致TCP握手的第三步ACK包不被接受.
之后就是對(duì)其中不同條件進(jìn)行觀察, 看看是哪個(gè)條件不通過(guò). 最終原因是accept隊(duì)列滿(sk_acceptq_is_full):
static inline bool sk_acceptq_is_full(const struct sock *sk){ return sk->sk_ack_backlog > sk- >sk_max_ack_backlog;}
恢復(fù)故障與日志的正關(guān)聯(lián)
在故障處理的一開始, 我們就檢查了syslog, 結(jié)論是未見異常.
當(dāng)整個(gè)故障分析完成, 得知了故障與syn cookie有關(guān), 回頭看syslog, 里面是有相關(guān)的信息, 只是和故障發(fā)生的時(shí)間不匹配, 沒(méi)有正關(guān)聯(lián), 因此被忽略.
檢查L(zhǎng)inux源碼:
if (!queue->synflood_warned &&
sysctl_tcp_syncookies != 2 &&
xchg(&queue->synflood_warned, 1) == 0)
pr_info(“%s: Possible SYN flooding on port %d. %s.
Check SNMP counters.\n”,
proto, ntohs(tcp_hdr(skb)->dest), msg);
可以看到日志受到了抑制, 因此日志與故障的正關(guān)聯(lián)被破壞.
粗看源碼, 每個(gè)listen socket只會(huì)發(fā)送一次告警日志, 要獲得日志與故障的正關(guān)聯(lián), 必須每次測(cè)試重啟MySQL.
解決方案
這種故障一旦形成, 難以檢測(cè); 系統(tǒng)日志中只會(huì)出現(xiàn)一次, 在下次重啟MySQL之前就不會(huì)再出現(xiàn)了; Client如果沒(méi)有合適的超時(shí)機(jī)制, 萬(wàn)劫不復(fù).
解決方案:
1. 修改MySQL的協(xié)議, 讓Client先發(fā)握手包. 顯然不現(xiàn)實(shí).
2. 關(guān)閉syn_cookie. 有安全的人又要跳出來(lái)了.
3. 或者調(diào)高syn_cookie的觸發(fā)條件 (syn backlog長(zhǎng)度). 降低系統(tǒng)對(duì)syn flood的敏感度, 使之可以容忍業(yè)務(wù)的syn波動(dòng).
有多個(gè)系統(tǒng)參數(shù)混合影響syn backlog長(zhǎng)度, 參看【
下圖為精華總結(jié)
請(qǐng)點(diǎn)擊輸入圖片描述
按我個(gè)人經(jīng)驗(yàn)有以下幾種方法:1.在連接數(shù)據(jù)庫(kù)的時(shí)候可以優(yōu)化,使用連接池。主要就是不要頻繁地創(chuàng)建,銷毀連接。這是很費(fèi)時(shí)的一個(gè)操作。因此,使用連接池來(lái)代替普通的建立連接操作,能提高并發(fā)度。2. 使用緩存技術(shù)。并不是每次都需要去數(shù)據(jù)庫(kù)里面查詢的,我們其實(shí)可以把前一次的查詢結(jié)果放在內(nèi)存里,如果下凱巧一次盯凱鍵用戶來(lái)查詢相同的內(nèi)容,直接內(nèi)存返回即可,不需要再次查詢。這樣可以大大降低查詢頻率。3.使用分布式技術(shù),將數(shù)據(jù)庫(kù)分布在多臺(tái)服務(wù)孫穗器上,同時(shí)也將用戶分區(qū)(如根據(jù)用戶ID的哈希值分區(qū)),不同的服務(wù)器負(fù)責(zé)不同用戶群,這樣就能大大減少單臺(tái)服務(wù)器的負(fù)載,使得整體的吞吐量提高。這幾樣技術(shù)可以同時(shí)使用,你的并發(fā)數(shù)量將獲得非常大的提高。
在連接數(shù)據(jù)庫(kù)的時(shí)候可以優(yōu)化,使用連接池。主要就是不要頻繁地創(chuàng)建,銷毀連接。這是很費(fèi)時(shí)的一個(gè)操作。因此,使用連接池來(lái)代替普通的建立連接操作,能提高并發(fā)度。
使用緩存技術(shù),并不是每次都需要去數(shù)據(jù)庫(kù)里面查詢的,我們其實(shí)可以把前一次的查詢結(jié)果放在內(nèi)存里,如果下一次用戶來(lái)查詢相同的內(nèi)容,直接內(nèi)存返回即可,不需要再次查詢。這樣可以大大降低查詢頻率。
使用分布式技術(shù),將數(shù)據(jù)庫(kù)分布在多臺(tái)服務(wù)器上,同時(shí)也將用戶分區(qū)(如根據(jù)用戶ID的哈希值分區(qū)),不同的服務(wù)器負(fù)責(zé)不同用戶群,這樣就能大大減少單臺(tái)服務(wù)器的負(fù)載,使得整體的吞吐量提高。這幾樣技術(shù)可以同時(shí)使用,你的并發(fā)數(shù)量將獲得非常大的提高。
大型數(shù)據(jù)庫(kù)介紹:
1 SQL Server
概括地說(shuō),SQL Server具有如下特點(diǎn):
A客戶/服務(wù)器體系結(jié)構(gòu);
B圖形化的用戶界面,使系統(tǒng)的管理更加直觀和簡(jiǎn)單。
C豐富的編程接口,為用戶進(jìn)行應(yīng)用程序設(shè)計(jì)提拱了更大的選擇余地。
D與Windows NT操作系統(tǒng)的有機(jī)集成,多線程體系結(jié)構(gòu)設(shè)計(jì),提供了系統(tǒng)對(duì)用戶并發(fā)訪問(wèn)的速度。
E對(duì)Web技術(shù)的支持,使用戶能夠很容易地將數(shù)據(jù)庫(kù)中的數(shù)據(jù)發(fā)布到網(wǎng)上。
F價(jià)格上的優(yōu)勢(shì)。與其他一些大型數(shù)據(jù)庫(kù)系統(tǒng)。如Oracle、Sybase等相比,SQL Server的價(jià)格非常便宜。
G作為微軟在Windows系列平臺(tái)上開發(fā)的數(shù)據(jù)庫(kù),SQL Server一經(jīng)推出就以其易用性和兼容性得到了很多用戶的青睞,是Windows環(huán)境商業(yè)應(yīng)用的首選數(shù)據(jù)庫(kù)。
2 Oracle
甲骨文公司(Oracle)的產(chǎn)品,可以運(yùn)行于很多操作系統(tǒng)之上(包括Windows),是大型企業(yè)級(jí)數(shù)據(jù)庫(kù)。Oracle它是以高級(jí)結(jié)構(gòu)化查詢語(yǔ)言為基礎(chǔ)的大型關(guān)系型數(shù)據(jù)庫(kù),是目前更流行的客戶/服務(wù)器體系機(jī)構(gòu)的數(shù)據(jù)庫(kù)之一。提供對(duì)Internet全面支持的管畝櫻閉理平臺(tái)和系統(tǒng)集成工具,完全支持所有的工業(yè)標(biāo)準(zhǔn),占有相當(dāng)大的市場(chǎng)份額。因其專業(yè)性較強(qiáng),操作繁雜,不易上手,價(jià)格較高,一般作為UNIX下的應(yīng)用較多,適于大型網(wǎng)站選用。
3 DB2
IBM公司的產(chǎn)品,可以運(yùn)行于很多操作系統(tǒng)上(包括Windows),是大型企業(yè)級(jí)數(shù)據(jù)庫(kù)。DB2具有很好的并行性。把數(shù)據(jù)庫(kù)管理擴(kuò)充到了并行的、多節(jié)點(diǎn)的環(huán)境。其操作簡(jiǎn)單、兼容性好,廣泛應(yīng)用于大型企業(yè)。
DB2是內(nèi)嵌于IBM的AS/400系統(tǒng)上的數(shù)據(jù)庫(kù)管理系統(tǒng),直接由硬件支持。它支持標(biāo)準(zhǔn)的SQL語(yǔ)言,具有與異種數(shù)據(jù)庫(kù)相連的GATEWAY。因此他具有速度快、可考性好的優(yōu)點(diǎn)。但是,只有硬件平臺(tái)選擇了IBM的AS/400,才能選擇使用DB2數(shù)據(jù)庫(kù)管理系統(tǒng)。
4 MySQL
MySQL是當(dāng)今UNIX或Linux類服務(wù)器上廣泛使用的Web數(shù)據(jù)庫(kù)系統(tǒng)。也可以運(yùn)行于Windows平臺(tái)。它是一個(gè)多用戶、多線程、跨平臺(tái)的SQL數(shù)據(jù)庫(kù)系統(tǒng),同時(shí)是具有客戶/服務(wù)器體系結(jié)構(gòu)的分布式數(shù)據(jù)庫(kù)管理系統(tǒng),屬自由數(shù)據(jù)庫(kù)系統(tǒng),開放源代碼數(shù)據(jù)庫(kù)產(chǎn)品。
MySQL于1996年誕生于瑞典的TcX公司。其設(shè)計(jì)思想為快捷、高效、實(shí)用。雖然它對(duì)ANSI SQL標(biāo)準(zhǔn)的支持并不完善,但支持所有常用的內(nèi)容,迅裂完全可以勝任一般Web數(shù)據(jù)庫(kù)的工作。由于它不支持事務(wù)處理,MySQL的速度比一些商業(yè)數(shù)據(jù)庫(kù)塊2-3倍,并且MySQL還針對(duì)很多操作平臺(tái)做了優(yōu)化,完全支持多CPU系統(tǒng)的多線程方式。
在編程方面,MySQL也提供了C、C++、Java、Perl、Python和TCL等API接口,而且有MyODBC接口,任何可以使用ODBC接口的語(yǔ)言都可以使用它。
MySQL是中小企業(yè)網(wǎng)站Linux平臺(tái)的首選。MySQL在Linux下應(yīng)用較多,Linux+MySQL+PHP是基于Linux的更佳組合。由于屬開放源代碼自由軟件,性價(jià)比較高,是中小企業(yè)網(wǎng)站、個(gè)人頌蘆網(wǎng)站不錯(cuò)的選擇。
怎樣在C語(yǔ)言中編寫多個(gè)程序并發(fā)執(zhí)行的程序
要實(shí)現(xiàn)完全的并發(fā)執(zhí)行,在一個(gè)CPU下實(shí)際上是不可能的
所說(shuō)的并發(fā),都是在同一個(gè)時(shí)間段內(nèi)
多個(gè)任務(wù)開始,交判氏掘替占用CPU,最終結(jié)束。
也就是前一個(gè)任務(wù)還沒(méi)結(jié)束,后一個(gè)任掘核務(wù)就開始了,一種并發(fā)的形式而已。
所以 要么使用多線程
要核啟么 手動(dòng)模擬這種多線程。
前者更常用。
多線程就可以
c 并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于c 并發(fā)訪問(wèn)數(shù)據(jù)庫(kù),使用 C 實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)的方法,大型網(wǎng)站數(shù)據(jù)庫(kù)系統(tǒng),怎么連接那么多并發(fā)數(shù)量的?,怎樣在C語(yǔ)言中編寫多個(gè)程序并發(fā)執(zhí)行的程序的信息別忘了在本站進(jìn)行查找喔。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過(guò)10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
網(wǎng)頁(yè)名稱:使用C實(shí)現(xiàn)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)的方法(c并發(fā)訪問(wèn)數(shù)據(jù)庫(kù))
文章轉(zhuǎn)載:http://m.fisionsoft.com.cn/article/dhgsjde.html


咨詢
建站咨詢
