本文使用pthread的庫,呼叫其中api可方便實現多執行緒效果。
本文主要講解實際中用到的幾個介面函式,足夠一般開發使用。
例項為應用與udp協議的收發,開啟接收資料執行緒,接收不影響主線程,主線程進行資料處理等工作,方便二次開發。
關於udp的教程可以參看:
首先介紹需要用到的介面函式。
1.pthread_create()函式
用於建立執行緒,呼叫該函式後,執行緒開始執行。建立成功時返回0。
int pthread_create(pthread_t *thread, const pthread_attr_t, void *(*_function)(void*), void *arg)
引數介紹:
a.第乙個引數為執行緒id的指標,建立方式為:
pthread_t
thread
[thread_num];
rc = pthread_create(*thread[i],null,null,null);
b.第二個引數為執行緒屬性設定,建立方式為:
pthread_attr_t attr; //執行緒屬性設定
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,pthread_create_joinable); //將屬性設定為joinable,可以使主線程等待該執行緒執行完後,再結束主線程
rc = pthread_create(*thread[i],&attr,null,null);
c.第三個引數為執行緒執行的函式&第四個引數為該函式需要的引數
該函式型別為 void*,即返回值為void*。引數型別為void*,如果要傳遞多個引數,可以建立乙個結構體進行傳遞。示例如下:
struct thread_recdata;
thread_recdata thread_rec; //建立函式所用引數
void *recinfo(void *rec_data); //建立函式
rc = pthread_create(&thread[0], &attr ,recinfo,(void *)&thread_rec); //開啟執行緒
pthread_attr_destroy(&attr); //釋放屬性attr的空間
2.pthread_join()函式
呼叫該函式可以阻塞主線程,等待子執行緒執行完後再結束主線程。如果不阻塞,可能出現主線程執行完,程式結束,但子執行緒還沒執行完的情況。
int pthread_join(pthread_t thread,void **status_value)
d第乙個引數為要等待子執行緒的id,第二個引數為返回的執行緒狀態資訊,其型別為void*。例項為:
void *status;
rc = pthread_join(thread[i], &status);
if (rc)
3.執行緒鎖
當兩個執行緒同時呼叫修改同乙個資料變數時,必須加執行緒鎖,否則將會出現資料錯亂的情況。資料加鎖後,其餘呼叫該變數的執行緒將會被阻塞,直到釋放鎖。例項如下:
pthread_mutex_t rec_mutex; //建立執行緒鎖
pthread_mutex_lock(&rec_mutex); //加鎖
rec_queue.push(thread_info->info); //修改資料
pthread_mutex_unlock(&rec_mutex); //解鎖
下面介紹乙個應用於udp協議的多執行緒例項:
本例開啟乙個接受執行緒不斷接受外部發來的資料,主線程處理這些資料,另開乙個顯示執行緒用作除錯。方便二次開發。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define port_in 12321
#define port_out 12322
#define num_thread 3
char info_rec[10][128];
pthread_mutex_t rec_mutex; //執行緒鎖
struct thread_senddata;
struct thread_recdata;
int initudp(void)
/*config socket addr*/
struct sockaddr_in addr;
socklen_t addr_len=sizeof(addr);
memset(&addr, 0, sizeof(addr));
addr.sin_family = af_inet; // use ipv4
addr.sin_port = htons(port_in); //
addr.sin_addr.s_addr = inet_addr("10.106.2.146");
/* time out*/
// struct timeval tv;
// tv.tv_sec = 0;
// tv.tv_usec = 200000; // 200 ms
// setsockopt(sockfd, sol_socket, so_rcvtimeo, (const char*)&tv, sizeof(struct timeval));
/* bind socket*/
if (bind(sockfd, (struct sockaddr*)&addr, addr_len) == -1)
return sockfd;
}void sendinfo(thread_senddata *thread_info) //傳送資料呼叫
}void *recinfo(void *rec_data) //接受執行緒呼叫的函式
}pthread_mutex_unlock(&rec_mutex);}}
}void *get_info_rec(void *arg) //顯示執行緒呼叫的函式
memset(info_rec[9],0,128);
}pthread_mutex_unlock(&rec_mutex);
//sleep(1);
}}int main(void)
/*設定接受執行緒引數*/
thread_rec.sockfd = sockfd;
thread_rec.info = buffer;
/*建立執行緒*/
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,pthread_create_joinable);
rc = pthread_create(&thread[0], &attr ,recinfo,(void *)&thread_rec); //收資料
if (rc)
rc = pthread_create(&thread[1], &attr ,get_info_rec,null); //顯示資料
if (rc)
/*設定傳送的資料*/
strcpy(info,"$hakqgs112233");
// strcpy(addr,"10.106.3.65");
strcpy(addr,"10.106.2.146");
thread_info.addr = addr;
thread_info.info = info;
thread_info.port = port_out;
thread_info.sockfd = sockfd;
while(1)
//刪除屬性,並等待其他執行緒
pthread_attr_destroy(&attr);
for(int i = 0 ;i < num_thread;i++)
}pthread_exit(null); //刪除執行緒
return
1;}
waldm c 多執行緒詳解
自我的部落格 atomic flag thread mutex recursive timed mutex 定時遞迴mutex類 lock類 unique lock 與mutex raii相關,方便執行緒對互斥量上鎖,但提供了更好的上鎖和解鎖控制 其他型別 函式 try lock 嘗試同時對多個互斥...
為何Linux廣泛應用於伺服器
在效能和穩定性上,linux不輸給任何作業系統,但是在桌面應用中,linux不再有其巨大優勢。可是這兩者需求不同,而這些不同正是linux適合應用於伺服器的根本所在。伺服器要求的是穩定性以及其效能,而linux的穩定性得到了公認,linux在設計時充分考慮了硬體元素,比如 linux在配置很低的硬體...
Linux下C語言多執行緒例項
建立兩個執行緒訪問互斥資料,對其加1輸出。這是乙個多執行緒最常見的例子 include include include include define max 10 pthread t thread 2 pthread mutex t mut int number 0,i void thread1 p...