『壹』 c語言實現多線程
目錄:
Linux操作系統,C語言實現多線程
Windows操作系統,C語言實現多線程
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;
}
『貳』 c語言epool怎麼和線程池一起使用
一, 背景
先說下我要實現的功能,server端一直在linux平台下面跑,當客戶端有請求過來的時候server端接受到請求,拿到客戶端的數據,根據拿到的數據做出相應的處理,得到處理的結果直接把結果數據發送給客戶端。這樣一個連接的請求結束,我的不是長連接的情況,不會一直保持客戶端的連接。來一個處理一個處理完了就結束了。
二,源碼下載(包括客戶端測試代碼)
我把邏輯處理部分簡單化了,如果這份代碼對你們有用的話,可以自己實現邏輯處理部分。
代碼是要傳入參數的,埠
代碼我已經在Linux下面編譯過了,也測試號了,因為代碼中用到了資料庫,如果你沒有編譯過可能要在Linux下裝Mysql資料庫。
源碼下載地址
三,代碼的簡單介紹
socket接受線程:C語言為了高並發所以選擇了epoll。當程序啟動的時候(g_net_update.c文件中main函數,會啟動一個thread見函數create_accept_task)這個thread就處理一件事情,只管接收客戶端的連接,當有連接進來的時候 通過epoll_ctl函數,把socket fd 加入到epoll裡面去,epoll設置監聽事件EPOLLIN | EPOLLET; 主要是監聽的是加入到epoll中的socket是否可讀(因為我的需求是客戶端連上了server就會馬上向server發送一份數據的)。其它的部分在主線程中處理。
主線程:是一個無線循環,epoll_wait 函數相當於把客戶端的連接從epoll中拿出來(因為我們監聽的是EPOLLIN | EPOLLET)說明這個時候客戶端有數據發送過來)。再通過recv_buffer_from_fd 函數把客戶端發送過來的數據讀出來。然後其他的一切就拋給線程池去處理。
線程池:(代碼中我會在池裡面創建15個線程) 雙向鏈表。加入線程就是在鏈表後面加一個鏈表項,鏈表的前面會一個一個被拿出來處理。主要是malloc 函數free函數,sem_wait函數sem_post的處理(sem_wait 會阻塞當值大於0是會減一,sem_post是值加一)。typedef void* (FUNC)(void arg, int index);是我們自定義的線程的邏輯處理部分,arg是參數,index是第幾個線程處理(我們隱形的給每個線程都標了號),例如代碼中的respons_stb_info,更加具體可以看看代碼裡面是怎麼實現的。聰明的你也可以改掉這塊的內容改成動態線程池,當某個時刻的處理比較多的時候能夠動態的增加線程,而不像我代碼裡面的是固定的。
資料庫連接池:按照我的需求在處理客戶端請求數據的時候是要訪問資料庫的。就是一下子創建出一堆的數據連接。要訪問資料庫的時候先去資料庫連接池中找出空閑的連接,具體可以看下代碼。使用的時候可以參考下database_process.c文件(代碼中資料庫連接池和線程池中的個數是一樣的)。這里我想說下get_db_connect_from_pool這個函數,我用了隨機數,我是為了不想每次都從0開始去判斷哪個連接沒有用到。為了資料庫連接池中的每個鏈接都能等概率的使用到,具體的還是可以看下代碼的實現。
log文件,代碼中是可以自動保存log信息到文件中去的,具體可以看下代碼。
四,碰到的一些問題和解決辦法
最初的時候server程序跑起來佔掉了linux 90%多的使用率,因為是我們在create_accept_task 中socket沒有設置成阻塞的。
server經常碰到一些莫名其妙的死機,沒辦法用了core mp 去抓死機的堆棧信息看在哪個函數死機的。
在處理資料庫的時候有的數據會自動的斷掉(說是說8個小時) 後來採用的辦法是每次都先mysql_ping一次讓他重新連接上。
就說幾點吧,其實還有好多其他的就不說了。
五,在Linux下面用到的幾個命令
./server程序名 & //加&後台運行。
killall server程序名 // 停掉server的運行。要在server目錄下面執行
netstat -antp|grep :埠號 // 查看埠下的socket狀態
ps -eaf | grep server程序名 // 檢查程序是否在運行,不過我一般是netstat -antp|grep :埠號 來看程序是否在運行。
好了 就到這里吧,如果你想實現Java的高並發可以稍微看下 Linux java + apache mina + maven 實現高並發伺服器
頂
2
踩
『叄』 基於Linux下的C語言編程
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<string.h>
int
main()
{
intfd;
char*p="hello";
charbuf[256]={0};
if(-1!=(fd=open("./new.txt",O_RDWR)))
{
if(-1!=write(fd,p,strlen(p)))
{
printf("WRITEOK ");
}
else
printf("WRITEFAILED ");
close(fd);
}
if(-1!=(fd=open("./new.txt",O_RDONLY)))
{
if(-1!=read(fd,buf,256))
printf("READ:%s ",buf);
close(fd);
}
return0;
}
『肆』 linux系統下,c語言pthread多線程編程傳參問題
3個線程使用的都是同一個info
代碼 Info_t *info= (Info_t *)malloc(sizeof(Info_t));只創建了一個info
pthread_create(&threads[i],NULL,calMatrix,(void *)info); 三個線程使用的是同一個
我把你的代碼改了下:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
intmtc[3]={0};//resultmatrix
typedefstruct
{
intprank;
int*mta;
int*mtb;
}Info_t;
void*calMatrix(void*arg)
{
inti;
Info_t*info=(Info_t*)arg;
intprank=info->prank;
fprintf(stdout,"calMatrix:prankis%d ",prank);
for(i=0;i<3;i++)
mtc[prank]+=info->mta[i]*info->mtb[i];
returnNULL;
}
intmain(intargc,char**argv)
{
inti,j,k=0;
intmta[3][3];
intmtb[3]={1};
Info_t*info=(Info_t*)malloc(sizeof(Info_t)*3);
for(i=0;i<3;i++)
for(j=0;j<3;j++)
mta[i][j]=k++;
/*3threads*/
pthread_t*threads=(pthread_t*)malloc(sizeof(pthread_t)*3);
fprintf(stdout," ");fflush(stdout);
for(i=0;i<3;i++)
{
info[i].prank=i;
info[i].mta=mta[i];
info[i].mtb=mtb;
pthread_create(&threads[i],NULL,calMatrix,(void*)(&info[i]));
}
for(i=0;i<3;i++)
pthread_join(threads[i],NULL);
fprintf(stdout," ====thematrixresult==== ");
fflush(stdout);
for(i=0;i<3;i++)
{
fprintf(stdout,"mtc[%d]=%d ",i,mtc[i]);
fflush(stdout);
}
return0;
}
矩陣的計算我忘記了,你運行看看結果對不對