筆者今天來講講Linux下多線程的使用。
在之前的串口通信和網絡通信中都使用到了多線程,今天就將這個碎碎唸的多線程好好講講。
很多時候會遇到一些阻塞式的函數,比如select()函數(監測某個標示符是否發生變化(之前的串口或者網絡通信標示符)),或者accept()函數,(等待客戶端的連接),這些函數一直會等待,直到監測到發生變化或者客戶端連接上,才退出,然後順序執行後面的任務。
如果採用單任務執行,那這樣阻塞嚴重影響其他任務的執行,所以這個時候就需要多任務處理(即"同時"執行很多個模塊化程序,互不耽誤)。筆者這裏講講使用多線程來進行多任務處理。
注意注意:在編譯的時候,如果使用多線程,要加上 -lpthread,
arm-linux-gnueabihf-gcc -g -c Mythread.c -o Mythread.o -lpthread
線程的創建函數 int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *),void *restrict arg );
參數1:線程ID
參數2:線程屬性,默認NULL
參數3:線程開始的地址,即要執行的函數入口地址
參數4:若上述函數需要參數,將參數放入結構中並將地址作爲arg傳入。
如果返回值不等於0,則創建失敗,否則創建成功。
線程結束:pthread_join(*pthread, NULL);
線程本身ID:pthread_self();
創建線程
int MyThreadStart(void*(*start_rountine)(void*),pthread_t *thread,void *arg)
{
memset(thread,0x00,sizeof(pthread_t));
int TempReturnValue;
TempReturnValue = pthread_create(thread,NULL,start_rountine,arg); //創建線程函數
if(TempReturnValue!=0)
{
printf("thread created failed!");
}
else
{
int id = pthread_self();
printf("thread id = %d",id);
}
return TempReturnValue;
}
結束線程
void MyThreadStop(pthread_t *pthread)
{
if(*pthread!=0)
{
pthread_join(*pthread, NULL);
printf("thread is over!");
}
}
線程上鎖與解鎖
爲避免多個線程同時使用一塊資源,比如同時操作一塊內存空間,就會引發錯誤。所以線程在使用的資源的時候,一定要上鎖,使用完成之後再解鎖。
pthread_mutex_t CCURec_mutex_t = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&CCURec_mutex_t );
DeQueue(TempPlatformRecQueue,&TempData);
pthread_mutex_unlock(&CCURec_mutex_t );
鬧鐘函數
相當於定時器函數,signal()指明時間到了觸發的函數,alarm()指明定時的時間。
void handler()
{
CCU_To_VST_IntersectionData();
alarm(T);
}
void TimerFunc()
{
signal(SIGALRM, handler); //註冊定時器處理函數
alarm(T); //鬧鐘函數
}
實際調用三個線程函數運行一下:
int temp = MyThreadStart(pthread_NetRecFun_Platform,&PlatformRec_Id,&ArgPlatformRec);
if(temp == 0)
{
printf("PlatformRecfun threadFunc successfully!\n");
}
temp = MyThreadStart(pthread_NetSendFun_Platform,&PlatformSend_Id,&ArgPlatformSend);
if(temp == 0)
{
printf("PlatformSendfun threadFunc successfully!\n");
}
temp = MyThreadStart(pthread_NetProcessFun_Platform,&PlatformProcess_Id,&ArgPlatformProcess);
if(temp == 0)
{
printf("PlatformProcessfun threadFunc successfully!\n");
}
void *pthread_NetRecFun_Platform(void *arg); //socket通信 接收線程函數
void *pthread_NetSendFun_Platform(void *arg); //socket通信 發送線程函數
void *pthread_NetProcessFun_Platform(void *arg); //socket通信 解析線程函數