linux下c 多執行緒詳解,應用於UDP

2021-08-01 17:31:41 字數 4239 閱讀 9915

本文使用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...