當前位置:首頁 » 數據倉庫 » c多線程操作資料庫
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c多線程操作資料庫

發布時間: 2023-06-11 12:45:48

c語言多線程的操作步驟

線程創建
函數原型:intpthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict attr,void *(*start_rtn)(void),void *restrict arg);
返回值:若是成功建立線程返回0,否則返回錯誤的編號。
形式參數:pthread_t*restrict tidp要創建的線程的線程id指針;const pthread_attr_t *restrict attr創建線程時的線程屬性;void *(start_rtn)(void)返回值是void類型的指針函數;void *restrict arg start_rtn的形參。
線程掛起:該函數的作用使得當前線程掛起,等待另一個線程返回才繼續執行。也就是說當程序運行到這個地方時,程序會先停止,然後等線程id為thread的這個線程返回,然後程序才會斷續執行。
函數原型:intpthread_join(pthread_tthread, void **value_ptr);
參數說明如下:thread等待退出線程的線程號;value_ptr退出線程的返回值。
返回值:若成功,則返回0;若失敗,則返回錯誤號。
線程退出
函數原型:voidpthread_exit(void *rval_ptr);
獲取當前線程id
函數原型:pthread_tpthread_self(void);
互斥鎖
創建pthread_mutex_init;銷毀pthread_mutex_destroy;加鎖pthread_mutex_lock;解鎖pthread_mutex_unlock。
條件鎖
創建pthread_cond_init;銷毀pthread_cond_destroy;觸發pthread_cond_signal;廣播pthread_cond_broadcast;等待pthread_cond_wait。

㈡ c語言實現多線程

目錄:

  1. Linux操作系統,C語言實現多線程

  2. Windows操作系統,C語言實現多線程

  3. Windows下的多線程(不帶停止)

Linux操作系統,C語言實現多線程:

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void*ThreadOne(void*threadArg)
{
printf("線程開始啦,參數是:%s ",(char*)threadArg);
returnNULL;
}
intmain(void)
{
pthread_tThreadID;/*記錄線程標識符*/
void*waitingResult;/*等待線程退出的等待結果*/
interrorCode;/*記錄線程的錯誤代碼*/
char*aMessage="這是線程的參數";
/*創建並啟動線程ThreadOne。若返回值非零,則線程創建失敗*/
errorCode=pthread_create(&ThreadID,NULL,ThreadOne,aMessage);
if(errorCode!=0)
{
printf("線程ThreadOne創建失敗。錯誤代碼:%d ",errorCode);
returnEXIT_FAILURE;
}
/*等待線程標識符為的ThreadID的線程結束*/
errorCode=pthread_join(ThreadID,&waitingResult);
if(errorCode!=0)
{
printf("等待線程退出等待失敗。錯誤代碼:%d ",errorCode);
returnEXIT_FAILURE;
}
printf("線程的返回值是%p ",waitingResult);
returnEXIT_SUCCESS;
}

Windows操作系統,C語言實現多線程:

#include<stdio.h>
#include<windows.h>
DWORDAPIENTRYThreadOne(LPVOIDthreadArg)
{
printf("線程開始啦,參數是:%s ",(char*)threadArg);
return0;
}
intmain(void)
{
HANDLEhThread;/*記錄線程句柄*/
DWORDThreadID;/*記錄線程ID號*/
DWORDwaitingResult;/*等待線程退出的等待結果*/
DWORDthreadExitCode;/*記錄線程的返回值*/
char*aMessage="這是線程的參數";
/*創建並啟動線程ThreadOne,返回值為線程句柄,賦值給hThread*/
hThread=CreateThread(NULL,0L,ThreadOne,(LPVOID)aMessage,0L,&ThreadID);
if(hThread==NULL)
{
printf("線程ThreadOne創建失敗。錯誤代碼:%lu ",GetLastError());
returnEXIT_FAILURE;
}
/*等待線程句柄為的hThread線程結束*/
waitingResult=WaitForSingleObject(hThread,INFINITE);
if(waitingResult==WAIT_FAILED)
{
printf("等待線程退出等待失敗。錯誤代碼:%lu ",GetLastError());
returnEXIT_FAILURE;
}
if(GetExitCodeThread(hThread,&threadExitCode))
printf("線程的返回值是%lu ",threadExitCode);
else
printf("獲取線程的返回值獲取失敗。錯誤代碼:%lu ",GetLastError());
returnEXIT_SUCCESS;
}

Windows下的多線程:(不帶停止)

#include<stdio.h>
#include<windows.h>
DWORDWINAPIoxianchen(LPVOIDlpParam);
intmain(intargc,char*argv[])
{
intnum=0;
CreateThread(NULL,NULL,oxianchen,&num,NULL,NULL);
while(1)
{
num++;
printf("主線程!%05d ",nu***eep(40);
}
return0;
}
DWORDWINAPIoxianchen(LPVOIDlpParam)
{
int*a=lpParam;
while(1)
{
++*a;
printf("副線程!%05d0x%p ",*a,a);
Sleep(80);
}
return0;
}

㈢ 多線程並發訪問資料庫並同時開啟事務的情況下,可能產生的問題包括

AB

C不是問題,C是可重復讀隔離級別下的一個正常現象。

㈣ C/C++用一個連接多線程並發訪問資料庫會不會有問題

加個原子鎖吧,盡量非同步訪問

㈤ 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++資料庫那種最快,支持多線程,或文本資料庫

選擇成品資料庫,要看之後的應用結構的才能確定用哪個快..
如果僅僅是要寫入時快,不考慮查詢情況..那當然直接把C/C++的數據結構給保存了最快..
比如保存一個struct Record,或class Record,限定好成員大小後,直接內存到磁碟的寫盤...
這樣寫最快,而讀取只能順序讀取....

另json等是交換格式不是存儲格式更不能當資料庫用哇....

㈧ 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);
}