linux有創(chuàng)建線程的函數(shù),即“pthread_create()”函數(shù)。該函數(shù)是類Unix操作系統(tǒng)中創(chuàng)建線程的函數(shù),支持四個參數(shù):參數(shù)1是指向線程標識符的指針、參數(shù)2用來設置線程屬性、參數(shù)3是線程運行函數(shù)的起始地址、參數(shù)4是運行函數(shù)的參數(shù)。
本教程操作環(huán)境:linux5.9.8系統(tǒng)、Dell G3電腦。
linux有創(chuàng)建線程的函數(shù),那就是pthread_create()函數(shù)。
pthread_create()是類Unix操作系統(tǒng)(Unix、Linux、Mac OS X等)中創(chuàng)建線程的函數(shù)
頭文件
#include<pthread.h>
函數(shù)聲明
int pthread_create( pthread_t *restrict tidp, //新創(chuàng)建的線程ID指向的內(nèi)存單元。 const pthread_attr_t *restrict attr, //線程屬性,默認為NULL void *(*start_rtn)(void *), //新創(chuàng)建的線程從start_rtn函數(shù)的地址開始運行 void *restrict arg //默認為NULL。上述函數(shù)需要參數(shù),將參數(shù)放入結(jié)構(gòu)中并將地址作為arg傳入。 );
返回值
-
若成功則返回0,否則返回出錯編號
參數(shù)
-
第一個參數(shù)為指向線程標識符的指針。
-
第二個參數(shù)用來設置線程屬性。
-
第三個參數(shù)是線程運行函數(shù)的地址。
-
最后一個參數(shù)是運行函數(shù)的參數(shù)。
注意
在編譯時注意加上-lpthread參數(shù),以調(diào)用靜態(tài)鏈接庫。因為pthread并非Linux系統(tǒng)的默認庫。
函數(shù)用法
#include <stdio.h> #include <string.h> #include <iostream> #include <pthread.h> #include <unistd.h> #include <vector> #include "main.h" using namespace std; struct Sample { uint32_t index; char sex; uint32_t age; uint32_t result; }; void* TaskEntry(void *args) { Sample *sa = (Sample*)args; uint32_t num = sa->index; if (num == 0) { printf("TaskEntry entry num = 0n"); // 線程1執(zhí)行體 sleep(10); printf("TaskEntry entry num = 0 is over!!!n"); } else if (num == 1) { printf("TaskEntry entry num = 1n"); // 線程2執(zhí)行體 sleep(10); printf("TaskEntry entry num = 1 is over!!!n"); } else if (num == 2) { printf("TaskEntry entry num = 2n"); // 線程3執(zhí)行體 sleep(2); printf("TaskEntry entry num = 2 is over!!!n"); } } uint32_t CreateTask(pthread_t& pid, Sample& sample) { // 假設Sample.index == 2創(chuàng)建任務失敗,直接返回 if (sample.index == 2) { return 2; } pthread_attr_t attr; // 設置線程屬性 pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 64 * 1024); // 設置線程棧大小為64KB uint32_t ret = pthread_create(&pid, &attr, (void*(*)(void*))TaskEntry, (void*)&sample); if (ret != 0) { return ret; } pthread_attr_destroy(&attr); // 取消線程的設置屬性 return 0; } void VerifyTask(vector<pthread_t>& taskID, vector<Sample>& taskArgs) { void *ret; for (int index = 0; index<2; index++) { // 等待線程結(jié)束,釋放相應的資源。pthread_join會堵塞主線程不會堵塞其他子線程,然后等待監(jiān)控的線程執(zhí)行完成,再返回主線程 // 在此處線程執(zhí)行順序為:線程1--主線程--線程2--主線程--線程3 pthread_join(taskID[index], &ret); // 堵塞主線程,執(zhí)行子線程taskID[index],等待子線程taskID[index]執(zhí)行完成釋放資源 printf("task[%d] is overn", index); // 主線程執(zhí)行打印操作 } } int main(void) { // 創(chuàng)建3個線程 vector<pthread_t> taskID(3); vector<Sample> taskArgs(3); for (int i = 0; i < 3; i++) { taskArgs[i] = { i, 'a', 90, 0}; uint32_t ret = CreateTask(taskID[i], taskArgs[i]); if (ret != 0) { // 模擬如下場景:任務創(chuàng)建失敗,直接停止前面的任務 for (int j = 0; j<i; j++) { pthread_cancel(taskID[j]); // 子線程1和子線程2延遲10s,當線程3創(chuàng)建失敗時,直接讓其停止。 } //return ret; // 主線程退出,所有子線程一起退出 } } VerifyTask(taskID, taskArgs); // 校驗線程是否結(jié)束 printf("three thead is running over!!!n"); return 0; }
注意編譯的使用需要加上編譯選項-lpthread,比如:g++ -lpthread main.cpp -o main