導航:首頁 > 網路營銷 > 分離線程semwait

分離線程semwait

發布時間:2021-02-10 23:39:31

1、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);
}

2、(計算機操作系統)wait操作和signal操作什麼意思?

wait操作和signal操作是計算機操作系統中進程式控制制的信號量機制的概念。

在進程式控制制中如何合理對共享資源分配便是一個關鍵的問題,所以引入了信號量的這個概念,通過pv操作便可以達到對空閑共享資源的合理分配。

一、信號量(semaphore)的數據結構為一個值和一個指針,指針指向等待該信號量的下一個進程。信號量的值與相應資源的使用情況有關。

1)、當它的值大於0時,表示當前可用資源的數量;

2)、當它的值小於0時,其絕對值表示等待使用該資源的進程個數。

二、PV操作,只有通過pv操作才可以改變信號量的值。

1)、p操作(wait):申請一個單位資源,進程進入。簡而言之就是信號量減一。

2)、v操作(signal):釋放一個單位資源,進程出來。簡而言之就是信號量加一。

(2)分離線程semwait擴展資料

信號量分類

1、整型信號量

最初Dijkstra把整型信號量定義為一個用於表示資源數目的整型量S,它與一般的整型量不同,除初始化外,僅能通過兩個標准原子操作(Atomic Operation)wait(S)和signal(S)操作。

2、記錄型信號量

在整型信號量機制中的wait操作,只要是信號量S<=0,就會不斷測試。因此,該機制並未遵循「讓權等待」准則,而是使進程處於「忙等」狀態。記錄型信號量機制則是一種不存在「忙等」現象的進程同步機制。

3、AND型信號量

在一些應用場合,是一個進程需要先獲得兩個或者更多的共享資源後方能執行其任務。假定現在有兩個進程A和B,他們都要求訪問共享數據D和E。當然,共享數據都應該作為臨界資源。為此,可為這兩個數據分別設置用於互斥的信號量Dmutex和Emutex。

4、信號量集

在記錄型信號量機制中,wait(S)或signal(S)操作僅能對信號量施以加1或者減1操作,意味著每次只能獲得或釋放一個單位的臨界資源。而當一次需要N個某類臨界資源時,便要進行N次wait(S)操作,顯然這是低效的。此外,在有些情況下,當資源數量低於某一下限值時,便不予分配。

3、sem_wait的函數說明

<

4、關於linux下的多線程使用sem信號量的運行問題

不是信號量的問題
printf函數,是先寫到輸出緩沖,遇到\n時,或者緩沖區滿時,或者有強制輸出(fflush)時,才會將緩沖區里的內容輸出到屏幕上(標准輸出設備:stdout)。你的代碼裡面並沒有以上3個觸發條件的任意一種,所以printf的內存沒有實際輸出到屏幕上。
你只要在每個printf函數後面加上fflush(stdout);就可以了。

5、電腦老藍屏,出現STOP,0×00000098 人家說DosMuxSemWait 沒有執行;設定太多的 sem aphore我要怎麼辦。

朋友,電腦藍屏的原因是很復雜的,這是軟體之間有沖突!【參考第3條】!
(答案原創,引用請說明原作者:力王歷史)
1。如果這是偶然,一般重啟電腦,症狀便可消失!
2。殺毒不徹底,(使用殺毒軟體,全盤掃描和自定義掃描)!
如果殺到木馬或病毒後,應立即重啟, 重啟電腦後,來到「隔離|恢復」,徹底刪除,木馬和病毒!
3。軟體沖突,不兼容:多餘的同類軟體安裝,(360管家,軟體卸載,找到卸載,再:強力清掃)!比如:播放器重復或有相似的,殺毒,瀏覽器,游戲,輸入法,下載工具,有同類多餘的,卸載多餘的,只留一款!
4。電腦系統有頑固的病毒和木馬或蠕蟲干擾,或者丟失了系統文件(360系統急
救箱或金山急救箱,金山網盾等等,其中任意一款,全盤查殺,再:系統修復)
5。軟體需要更新,(360管家,軟體升級,下載,覆蓋安裝,winrar可以不升)
6。系統有新的漏洞等待安裝,(修補高危和重要的,其它設置為:忽略)
7。顯卡或內存cpu,或風扇的接觸不良和松動或有灰塵覆蓋,(拔下橡皮擦擦)注意是:台式機!
8。內存cpu過熱,散熱性不好!(開機時間不要太長,關機散熱)
9。電腦存在惡評插件! (掃描出來,立即清理)
10。電腦磁碟碎片過多,(開始,程序,附件,系統工具,磁碟碎片整理程序)!
11。如果還是不行,說明系統文件丟失了!或者系統內存有很嚴重的錯誤了!
12。重啟開機,出完電腦品牌後,按F8,進安全模式里,最後一次正確配置,回車,回車,按下去,試試!
13。玩游戲藍屏,一般就是系統不支持這款游戲!(更換游戲版本)
14。下載的游戲,播放器,輸入法,下載工具,瀏覽器,驅動,等等的程序不穩定!(卸載重裝或升級至最新版本)!
15。如果還是不行,需要「一鍵還原」系統或「重裝系統」了 !

本答案並非網路復制,全部是本人:「力王歷史」,長期在「百度知道」總結和自己實踐,以及廣大的百度網友們,反饋得來的經驗!

與分離線程semwait相關的知識