【Linux】信號的控制使用
- 一.線程的創建
- pthread_create()接口
- 二.線程等待
- 1.為什么要線程等待?
- 2.pthread_join()
- 三.線程中止
- 1.return
- 2.pthread_exit
- 五.線程應用
- C++自帶多線程
在上次的博客中主要講解了什么是線程
這次的博客主要是帶大家把線程的相關接口簡單的使用一下
這次博客的篇幅不長,就單純了解接口的,之后的博客才會來主要剖析線程
首先在Linux中有一個原生線程庫
Linux中沒有線程的概念,但是用戶肯定是需要線程這個東西的
所以說Linux中有一個原生線程庫(基本上所有的Linux中都有)
叫做pthread.h
,正是這個原生線程庫給用戶提供了Linux中的線程的這個概念
這個博客接下來就是帶大家來認識一下比較常用的原生線程庫中的接口的
一.線程的創建
pthread_create()接口
這里帶大家來認識一下對應的參數
大致就是這么個用處
#include<iostream>
#include<pthread.h>
#include<unistd.h>
void* run_pthread(void* argv)
{std::cout<<*(int*)argv<<std::endl;
}int main()
{pthread_t lwp_id;int i=10;pthread_create(&lwp_id,nullptr,run_pthread,(void*)&i);sleep(5);}
這邊隨便寫一個用用
這里可能有人注意到,為什么要sleep(5)
眾所周知,主線程和子線程是同時運行的,創建完子線程,這個主線程就直接結束了
所以說這個int i的變量直接就在主線程中被銷毀了
所以說接下來就引出了線程等待
二.線程等待
1.為什么要線程等待?
首先什么是線程等待?
我們在什么地方看到過等待?
就是我們以前在進程博客中寫過的,進程等待
還記得為什么父子進程要等待嗎
因為你父進程把子進程生了下來,你不能不管啊
如果你父進程結束了,子進程沒有人來回收,那就變成孤兒進程和僵尸進程了
映射到我們線程,其實原理也差不多
但是還是有一點不一樣的。
進程是獨立的,但是線程是進程的執行流
當主線程結束后(也就是main函數結束),所有的子進程也會中斷
那為什么要等待呢?
1.資源回收
線程退出時,其棧內存和系統資源不會自動釋放,需要等待來正確釋放
2.同步執行順序:
確保某些操作在其他線程完成后執行
3.獲取返回值:
就是進程執行的結果
所以說我們要介紹一個線程等待的接口
可以接受線程執行結果的返回值,而且是阻塞等待
2.pthread_join()
接口大致就是這樣的思路
#include<iostream>
#include<pthread.h>
#include<unistd.h>
void* run_pthread(void* argv)
{std::cout<<*(int*)argv<<std::endl;
}int main()
{pthread_t lwp_id;int i=10;pthread_create(&lwp_id,nullptr,run_pthread,(void*)&i);pthread_join(lwp_id,nullptr);
}
這里我們把sleep,直接換成了 pthread_join(lwp_id,nullptr);
因為是阻塞等待,只會等待子線程處理完,才會結束,所以i的生命周期還在,沒有被銷毀
這里其實一直有個編譯警告,這里沒有放出來
意思就是子線程沒有返回值
這里就帶大家把這個等待線程的接受子線程返回值給用用
#include<iostream>
#include<pthread.h>
#include<unistd.h>
void* run_pthread(void* argv)
{std::cout<<*(int*)argv<<std::endl;return (void*)(intptr_t)1;
}int main()
{pthread_t lwp_id;int i=10;pthread_create(&lwp_id,nullptr,run_pthread,(void*)&i);void* ret;pthread_join(lwp_id,&ret);std::cout<<"running end= "<<(intptr_t)ret<<std::endl;
}
這個intptr_t是C++庫中的一個整數類型,它專門用于安全地存儲指針值
intptr_t 是一個有符號整數類型,其大小能夠容納任何有效的指針值
子線程執行結果是通過void*來返回的
所以說我們在子進程中返回void*
然后在pthread_join
中接受的返回值是void()**
二級指針就是接受一級指針的地址的,所以用取地址
這里要注意一點:
為什么在pthread_join中不考慮異常,只考慮返回值
因為線程出現異常問題,整個線程都完了,所以只有進程才會去考慮異常
三.線程中止
這個其實就是如何返回進程的返回值的:
1.return
這個我們在上面的代碼中使用過了,接下來就隨便用用下一個
2.pthread_exit
這個其實就當return用就行
#include<iostream>
#include<pthread.h>
#include<unistd.h>
void* run_pthread(void* argv)
{std::cout<<*(int*)argv<<std::endl;pthread_exit((void*)(intptr_t)1);
}int main()
{pthread_t lwp_id;int i=10;pthread_create(&lwp_id,nullptr,run_pthread,(void*)&i);void* ret;pthread_join(lwp_id,&ret);std::cout<<"running end= "<<(intptr_t)ret<<std::endl;
}
五.線程應用
C++自帶多線程
c++11也已經支持多線程
#include<iostream>
#include<thread>void run_code()
{std::cout<<"i am ok"<<std::endl;}int main()
{std::thread t(run_code);t.join();return 0;}
但其實在Linux中的C++的多線程也是封裝的,底層用的還是pthread的原生線程庫
因為你編譯的時候,還是需要-lpthread
來鏈接原生線程庫
不管是什么語言,底層都是調用的原生線程庫,進行封裝的
推薦使用語言自帶的,因為具有可移植性