① 多線程cpu有什麼好處
CPU多線程簡稱SMT,可通過復制處理器上的結構狀態,讓同一個處理器上的多個線程同步執行並共享處理器的執行資源,可最大限度地實現寬發射、亂序的超標量處理,提高處理器運算部件的利用率,緩和由於數據相關或Cache未命中帶來的訪問內存延時。
註:當沒有多個線程可用時,SMT處理器幾乎和傳統的寬發射超標量處理器一樣。
cpu的多線程技術可以為高速的運算核心准備更多的待處理數據,減少運算核心的閑置時間;解決了負載均衡問題,充分利用了CPU資源,提高CPU的使用率。採用多線程的方式可以同時完成幾件事情而不互相干擾,縮短了處理大量的IO操作時或處理的情況需要花費大量的時間。
多線程的好處:
1、使用線程可以把占據時間長的程序中的任務放到後台去處理
2、用戶界面更加吸引人,這樣比如用戶點擊了一個按鈕去觸發某件事件的處理,可以彈出一個進度條來顯示處理的進度
3、程序的運行效率可能會提高
4、在一些等待的任務實現上如用戶輸入,文件讀取和網路收發數據等,線程就比較有用了.
多線程的缺點:
1、如果有大量的線程,會影響性能,因為操作系統需要在它們之間切換.
2、更多的線程需要更多的內存空間
3、線程中止需要考慮對程序運行的影響.
4、通常塊模型數據是在多個線程間共享的,需要防止線程死鎖情況的發生
② c++資料庫那種最快,支持多線程,或文本資料庫
選擇成品資料庫,要看之後的應用結構的才能確定用哪個快..
如果僅僅是要寫入時快,不考慮查詢情況..那當然直接把C/C++的數據結構給保存了最快..
比如保存一個struct Record,或class Record,限定好成員大小後,直接內存到磁碟的寫盤...
這樣寫最快,而讀取只能順序讀取....
另json等是交換格式不是存儲格式更不能當資料庫用哇....
③ C#多線程寫資料庫
首先對資料庫(尤其是Access)使用多線程大多不會提高效率(除非sql中有耗時但不好資源的操作,如T-SQL中休眠之類的語句)。
建議樓主:使用隊列,將要執行的SQL語句放入隊列中(如:System.Collection.Queue或ArrayList),然後用一根線程一條一條執行,另外Access不支持事物回滾只有自己想辦法實現了。濫用多線程會加大程序開發的難度,以及包括程序的不穩定。
另外:cbyvft的答案「……所有的線程使用同一個連接」
,是嚴重錯誤的!!連接對象Connection不能迸發,也就是不能多根線程共享一個連接對象,否則很容易引發異常(報錯為:...基礎對象與RAW分離之類的信息)。
若非要用多線程來做,我可以給你一段代碼(我以前開發的項目中一部分),請加我的「網路Hi」並發消息給我,我傳給你。
我不在這里帖代碼了,因為實現的代碼較多,而且比較復雜(使用多線程要考慮很多問題,代碼要碩壯通用,所以代碼量較大)。
④ C/C++多線程問題
WINDOWS線程需要這樣的函數體:
DWORD WINAPI thread_proc(LPVOID lpParam)
{
...
return 0;
}
C語言中直接調用線程就是CreateThread(&thread_proc, ...)即可
因為C++的類是在運行階段分配地址,而不是在編譯階段分配地址,所以要想在類函數中聲明線程,就必須強制把線程成員函數設置為編譯階段就分配地址,這樣才能綁定到WINDOWS API的CreateThread函數上去,這種方式叫做static.
之所以保存線程指針是因為現代多任務操作系統往往處於比較復雜的狀態。比如,假設你的線程是用於下載某個網路資源,如電影等;同時網路用戶調整了帶寬,或者開始打游戲,或者播放視頻,這些都會影響CPU對當前定義的線程的資源控制。如果線程內部涉及了很多資源,如果不進行善後則後果比較嚴重(假設你的線程在下一個電影的局部片段,因為資源沒有正常退出,導致整個電影文件即使全部下載下來也無法打開)。所以為了妥善處理,一般好的軟體在主程序接到退出、終止、異常時,首先都會嘗試【安全】退出線程,逐步關閉已打開的資源,如文件、資料庫、管道、網路連接等等,再徹底退出。
假如你的線程用於網路游戲,那就更典型了,你不希望因為一時斷網,導致下次再上的時候,裝備全丟吧?
⑤ C# 多線程 大量數據實時接收\解析\存儲 問題
1、定義兩個線程安全的隊列(System.Collections.Concurrent.ConcurrentQueue<T>)a跟b,其中a用於儲存接受的數據,b用於儲存要持久化的數據。
2、線程A循環讀取數據並儲存到隊列a中。
3、線程B循環從隊列a中讀取數據。
3.1、如果讀取到數據
3.1.1、將解析前的數據跟解析後的數據賦值給專門儲存它們的類c。
3.1.2、將類c添加到隊列b中。
3.1.3、將解析後的數據顯示到UI線程中。
3.2、如果沒有讀取到數據,則sleep一定時間。
4、線程C循環從隊列b中讀取數據。
4.1、如果讀取到數據,則儲存數據。
4.2、如果沒有讀取到數據,則sleep一定時間。
5、線程D可以不要,不過假設數據的處理時間過長,將導致隊列長度不斷增長,所以線程D可以循環判斷隊列a跟隊列b的長度。假設隊列中的對象數量超過特定閥值,則進行一定處理。比如終止程序,比如跳過部分數據,比如停止接收數據等。
⑥ C語言,OCI多線程建立session的問題,需要一個多線程連接的示例代碼
。。
你子線程式控制制同步了么? 斷錯誤一般是內存操作出錯 和oci 或者pthread的關系不大!
void* OracleProcess(GPS_DATA GpsRec) // 資料庫數據處理
{
interval = 0;
struct HashItem* pHash;
pHash = inithashtable(MAX_REC<<2);
char sql[384] = {0};
char temp[256] = {0};
char tName[10] = {0}; // 表名字
int i,k;
int j = TotalRec >> RATE;
double distance;
for(i=0; i < j; i++)
{
sprintf(temp,"%s%f%f%f%d",gps_last[i].tid,gps_last[i].lon,gps_last[i].lat,gps_last[i].speed,gps_last[i].udate);
InsertHash(temp, pHash, MAX_REC<<2); // 插入最後GPS信息到hash
memset(temp,0x00,256);
}
for(i = 0; i < TotalRec; i++)
{
for(k=0; k<j; k++) // 查詢車機是否在冊
if(strcmp(GpsRec[i].tid,tid[k]) == 0)
break;
if(k < j)
{
if(GpsRec[i].udate != 0.00)
{
distance = InfoUpdate(GpsRec,i); // 最新GPS數據更新
sprintf(temp,"%s%f%f%f%d",GpsRec[i].tid,GpsRec[i].lon,GpsRec[i].lat,GpsRec[i].speed,GpsRec[i].udate);
if(GetHashTablePos(temp, pHash, MAX_REC<<2) == -1) // 查找hash是否存在
{
if (distance > 0.0001)
{
sprintf(tName,"GPS_%d_Y",tf[k]);
InsertHash(temp, pHash, MAX_REC<<2); // 插入
sprintf(sql,"insert into %s (id,tm_id,lon,lat, speed, utc_time, udate,mileage,DIRECTION,DISTANCE) values (seq_gps.nextVal,'%s','%f','%f','%f','%d','%d','%f','%d','%f','%d')",
tName,GpsRec[i].tid,GpsRec[i].lon,GpsRec[i].lat,GpsRec[i].speed,GpsRec[i].utime,GpsRec[i].udate,GpsRec[i].mileage,GpsRec[i].dir,distance,interval);
printf("%s\n",sql);
oci_excu(oracle_env,(text *)sql,0); // 插入數據
memset(tName,0x00,10);
}
}
memset(sql,0x00,384);
memset(temp,0x00,256);
}
}
}
memset(GpsRec,0x00,sizeof(GpsRec));
free(pHash);
pthread_exit(NULL);
}
void TcpProcess(int tfd) // 處理TCP連接上的事務
{
struct timeval ntime;
int index = 0,times,ret;
int rlen = 0,rflag = 0;
char recvbuf[513] = {0};
bzero(recvbuf,513);
while(1)
{
ret = rlen = read(tfd,recvbuf,512);
if(rlen <= 0)
break;
if((rlen%32) == 0) // 32長度為標准TCP信息
{
times = 0;
ret >>= 5;
while(ret--)
{
if(tflag[tfd] == tfd) // 已經存在的socket
{
LOVENIX *info = (LOVENIX *)malloc(sizeof(LOVENIX));
memset(info,0x00,sizeof(LOVENIX));
if(recvbuf[times] == 0x58 || recvbuf[times] == 0x59)
ProtocolAnalysisLovenixTcp(&recvbuf[times],info);
else if(recvbuf[times] == 0x24)
ProtocolAnalysisLovenixUdp(&recvbuf[times],info);
sprintf(info->tid,"%s",seq[tfd]); // 合成車輛ID
DataProcess(info); // 處理GPS數據
free(info);
gettimeofday(&ntime, NULL);
cntime[tfd] = ntime.tv_sec; // 更新時間
times += 32;
}
}
}
else if(rlen > 32)
{
if(!rflag)
{
if((index = RegLovenix(tfd,recvbuf)) > -1)
{
sprintf(seq[tfd],"%s",tid[index]); // 將對應的socket設備ID保存
gettimeofday(&ntime, NULL);
sfd[tfd] = tfd;
cntime[tfd] = ntime.tv_sec;
tflag[tfd] = tfd;
rflag = 1;
}
}
}
if(rlen < 512); // 已經讀完
break;
memset(recvbuf,0x00,rlen);
}
}
void *TcpServer(void *arg)
{
int port = (unsigned int) arg;
int efd,i;
struct timeval ntime;
int listener, nfds, n, listen_opt = 1, lisnum;
struct sockaddr_in my_addr, their_addr;
socklen_t len = sizeof(their_addr);
lisnum = MAXLISTEN;
for(i=0; i<MAX_REC; i++)
{
sfd[i] = 0;
tflag[i] = 0;
}
if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) // 開啟 socket 監聽
{
lprintf(lfd, FATAL, "TCP Socket error!\n");
exit(1);
}
else
lprintf(lfd, INFO, "TCP socket creat susscess!\n");
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (void *) &listen_opt,(int) sizeof(listen_opt)); // 設置埠多重邦定
setnonblocking(listener);
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = PF_INET;
my_addr.sin_port = htons(port);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1)
{
lprintf(lfd, FATAL, "TCP bind error!\n");
exit(1);
}
else
lprintf(lfd, INFO, "TCP bind susscess!\n");
if (listen(listener, lisnum) == -1)
{
lprintf(lfd, FATAL, "TCP listen error!\n");
exit(1);
}
else
lprintf(lfd, INFO, "TCP listen susscess!\n");
kdpfd = epoll_create(MAXEPOLLSIZE); // 創建 epoll句柄,把監聽socket加入到epoll集合里
ev.events = EPOLLIN | EPOLLET; // 注冊epoll 事件
ev.data.fd = listener;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0)
lprintf(lfd, FATAL, "EPOLL_CTL_ADD error!\n");
while (1)
{
sem_wait(&sem_tcp); // 等待 sem_TCP
sem_wait(&sem_tp); // 將tp值減一
nfds = epoll_wait(kdpfd, events, MAXEPOLLSIZE, 1); // 等待有事件發生
if (nfds == -1)
lprintf(lfd, FATAL,"EPOLL_WAIT error!\n");
for (n = 0; n < nfds; ++n) // 處理epoll所有事件
{
if (events[n].data.fd == listener) // 如果是連接事件
{
if ((efd = accept(listener, (struct sockaddr *) &their_addr,&len)) < 0)
{
lprintf(lfd, FATAL, "accept error!\n");
continue;
}
else
lprintf(lfd, INFO, "Client from :%s\tSocket ID:%d\n", inet_ntoa(their_addr.sin_addr) ,efd);
setnonblocking(efd); // 設置新連接為非阻塞模式
ev.events = EPOLLIN | EPOLLET; // 注冊新連接
ev.data.fd = efd;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, efd, &ev) < 0) // 將新連接加入EPOLL的監聽隊列
lprintf(lfd, FATAL, "EPOLL_CTL_ADD error!\n");
else
{
gettimeofday(&ntime, NULL);
cntime[efd] = ntime.tv_sec;
sfd[efd] = efd;
}
}
else if (events[n].events & EPOLLIN)
tpool_add_work(pool, TcpProcess, (void*)events[n].data.fd); // 讀取分析TCP信息
else
{
close(events[n].data.fd);
epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd, &ev);
}
}
sem_post(&sem_cm);
sem_post(&sem_udp);
}
close(listener);
}
int DataProcess(LOVENIX *info) // 處理GPS數據
{
if(sflag == 0 && (CacheRec != TotalRec)) // 緩存1可用且沒有滿
{
gps_cache[CacheRec].lat = info->lat;
gps_cache[CacheRec].mileage = info->mileage;
gps_cache[CacheRec].lon = info->lon;
gps_cache[CacheRec].speed = atod(info->speed, strlen(info->speed))*0.514444444*3.6;
gps_cache[CacheRec].udate = atoi(info->udate);
gps_cache[CacheRec].utime = atoi(info->utime);
gps_cache[CacheRec].dir = atoi(info->dir);
sprintf(gps_cache[CacheRec].tid ,"%s",info->tid);
CacheRec++;
// printf("CacheRec %d\tTotalRec %d \t sflag:%d\n",CacheRec,TotalRec,sflag);
if(CacheRec == TotalRec)
{
sflag = 1;
pthread_attr_init(&attr); // 初始化屬性值,均設為默認值
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 設置線程為分離屬性
if (pthread_create(&thread, &attr,(void*) OracleProcess,(void*)gps_cache)) // 創建數據處理線程
lprintf(lfd, FATAL, "oracle pthread_creat error!\n");
CacheRec = 0;
}
}
else if(sflag == 1 && (Cache1Rec != TotalRec)) // 緩存2可用且沒有滿
{
gps_cache1[Cache1Rec].mileage = info->mileage;
gps_cache1[Cache1Rec].lat = info->lat;
gps_cache1[Cache1Rec].lon = info->lon;
gps_cache1[Cache1Rec].speed = atod(info->speed, strlen(info->speed))*0.514444444*3.6;
gps_cache1[Cache1Rec].udate = atoi(info->udate);
gps_cache1[Cache1Rec].utime = atoi(info->utime);
gps_cache1[Cache1Rec].dir = atoi(info->dir);
sprintf(gps_cache1[Cache1Rec].tid ,"%s",info->tid);
Cache1Rec++;
if(Cache1Rec == TotalRec)
{
sflag = 0;
pthread_attr_init(&attr); // 初始化屬性值,均設為默認值
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 設置線程為分離屬性
if (pthread_create(&thread, &attr,(void*) OracleProcess,(void*)gps_cache1)) // 創建數據處理線程
lprintf(lfd, FATAL, "oracle pthread_creat error!\n");
Cache1Rec = 0;
}
}
else
{
lprintf(lfd, FATAL, "No cache to use!\n");
return (0);
}
return (1);
}
⑦ C語言如何實現多線程同時運行
1、點擊菜單欄的「Project」選項卡,下拉列表的最後一項「Project options...」是對當前工程的的屬性進行設置的。
⑧ C/C++用一個連接多線程並發訪問資料庫會不會有問題
加個原子鎖吧,盡量非同步訪問
⑨ 多線程並發訪問資料庫並同時開啟事務的情況下,可能產生的問題包括
AB
C不是問題,C是可重復讀隔離級別下的一個正常現象。
⑩ 用pro*c/c++ 和qt creator工具讓C++連接Oracle資料庫的問題。
資料庫連接作為一種資源,我們的應用必須對之進行行之有效的管理。我們在訪問資料庫的時候,一般傳統上採用先建立連接,然後使用該連接訪問資料庫,在使用完畢後,關閉該連接。這是我們經常採用的方法。該方法的好處是使用簡單,不用對連接進行任何管理。但隨之帶來的缺點也就出現了,在應用需要頻繁訪問資料庫的時候,這種方法就會使程序的效率十分低下,甚至有時候是不能滿足應用的需要的。隨著資料庫連接池技術出現了,我們的應用根據訪問資料庫的頻率動態決定創建連接的數量,以及決定在適當的時刻可以關閉一些資料庫連接,用以節省這種資源。筆者最近在參考了網上大量代碼的同時,實現了如何利用Pro C++使用資料庫連接池完成了多線程對oracle資料庫的訪問。本著來源於網路,共享與網路的精神,和大家共同探討,其中筆者的大部分代碼來源是黃劍鋒先生的共享代碼,在此深表感謝。實現的基本功能如下:1:可以設定最小的資料庫連接數。2:可以設定最大的資料庫連接數。3:當資料庫某個連接空閑時間多長時間後,該連接池會自動斷開連接以節省資料庫連接資源。4:提供了每個連接被使用的次數介面,方便統計和分析各個連接的情況。5:提供了每個連接從上次訪問完畢,懂查看的時候為止,已經空閑的時長,以秒為單位。6:可以動態訪問資料庫存儲過程,即存儲過程的名字可以動態變化的。
代碼庫:http://blog.csdn.net/wayneforever/article/details/9028901
望採納,謝謝