c++多線程學習
學習資料來源於C++多線程菜鳥教程:c++多線程
本人使用環境 manjaro ide爲vscode c++11,
這裏需要注意,對於線程相關代碼編譯時需加入 -lpthread 即 g++ a.cpp -plthread
否則會顯示undefined reference to `pthread_create'
我這裏使用爲vscode按照剛開始配置文件無法通過vsc直接編譯,但是可以修改tasks.json文件
在args裏面加入 "-lpthread"即可 以下給我我的配置文件 修改後可直接編譯運行
{
"version": "2.0.0",
"tasks": [
{
"label": "Compile", // 任務名稱,與launch.json的preLaunchTask相對應
"command": "clang++", // 要使用的編譯器
"args": [
"${file}",
"-o", // 指定輸出文件名,不加該參數則默認輸出a.exe,Linux下默認a.out
"${fileDirname}/${fileBasenameNoExtension}.exe",
"-g", // 生成和調試有關的信息
"-Wall", // 開啓額外警告
"-static-libgcc", // 靜態鏈接
"-lpthread",
"-fcolor-diagnostics", // 彩色的錯誤信息?但貌似clang默認開啓而gcc不接受此參數
"-std=c++11" // C語言最新標準爲c11,或根據自己的需要進行修改
], // 編譯命令參數
"type": "shell", // 可以爲shell或process,前者相當於先打開shell再輸入命令,後者是直接運行命令
"group": {
"kind": "build",
"isDefault": true // 設爲false可做到一個tasks.json配置多個編譯指令,需要自己修改本文件,我這裏不多提
},
"presentation": {
"echo": true,
"reveal": "always", // 在“終端”中顯示編譯信息的策略,可以爲always,silent,never。具體參見VSC的文檔
"focus": false, // 設爲true後可以使執行task時焦點聚集在終端,但對編譯c和c++來說,設爲true沒有意義
"panel": "shared" // 不同的文件的編譯信息共享一個終端面板
}
// "problemMatcher":"$gcc" // 如果你不使用clang,去掉前面的註釋符,並在上一條之後加個逗號。照着我的教程做的不需要改(也可以把這行刪去)
}
]
}
接下開始學習多線程:
首先是線程的創建
pthread_create (thread, attr, start_routine, arg)
該函數有4個參數,分別代表
thread | 指向線程標識符指針。 |
attr | 一個不透明的屬性對象,可以被用來設置線程屬性。您可以指定線程屬性對象,也可以使用默認值 NULL。 |
start_routine | 線程運行函數起始地址,一旦線程被創建就會執行。 |
arg | 運行函數的參數。它必須通過把引用作爲指針強制轉換爲 void 類型進行傳遞。如果沒有傳遞參數,則使用 NULL。 |
看起來可能不是很清楚,直接上代碼。
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=5
void *PrintHello(void *threadid)
{
int tid = *((int*)threadid);// 對傳入的參數進行強制類型轉換,由無類型指針變爲整形數指針,然後再讀取
cout << "Hello Runoob! 線程 ID, " << tid << endl;
pthread_exit(NULL);
}
int main ()
{
pthread_t threads[maxn];
int indexes[maxn];// 用數組來保存i的值
for(int i=0; i < NUM_THREADS; i++ )
{
cout << "main() : 創建線程, " << i << endl;
indexes[i] = i; //先保存i的值
// 傳入的時候必須強制轉換爲void* 類型,即無類型指針
int rc = pthread_create(&threads[i], NULL,PrintHello,(void *)&(indexes[i]));
if (rc)
{
cout << "Error:無法創建線程," << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
可以看到4個參數中,第3個參數代表該線程需要完成的任務,而最後一個參數是將在線程開始函數的傳入的參數,那麼有個問題,如何給函數傳入多個參數呢,
#include <bits/stdc++.h>
using namespace std;
const int maxn=5;
struct thread_data//創建一個結構體 格式爲將傳入的參數
{
int thread_id;
char *message;
};
void *print(void *threadarg)//函數這裏傳入的仍未空指針
{
thread_data *mydata;
mydata=(thread_data*) threadarg;//通過強制類型轉換將參數列表提取出來
cout<<"Thread ID: "<<mydata->thread_id<<endl;
cout<<"Thread message: "<<mydata->message<<endl;
pthread_exit(NULL);
}
int main()
{
pthread_t tids[maxn];
thread_data td[maxn];//輸入參數
for(int i=0;i<5;i++)
{
cout<<"main() : create thread, "<<i<<endl;
td[i].thread_id=i;
td[i].message="makise kurisu";
int rc=pthread_create(&tids[i],NULL,print,(void*)&td[i]);//參數強轉爲void*
if(rc)
{
cout<<"error"<<endl;
exit(-1);
}
}
pthread_exit(NULL);
}
可以看到 通過類型強轉實現了函數傳入多個參數的方法,目前我只學習了這一個寫法,不清楚有沒有其他的,日後在更,現在的目的只是單純的瞭解多線程的基礎操作和原理。