linux線程屬性
① linux線程阻塞問題
pthread_join一般是主線程來調用,用來等待子線程退出,因為是等待,所以是阻塞的,一般主線程會依次join所有它創建的子線程。
pthread_exit一般是子線程調用,用來結束當前線程。
子線程可以通過pthread_exit傳遞一個返回值,而主線程通過pthread_join獲得該返回值,從而判斷該子線程的退出是正常還是異常。
② linux 進程回收線程資源指哪些資源
Linux系統中程序的線程資源是有限的,表現為對於一個程序其能同時運行的線程數是有限的。而默認的條件下,一個線程結束後,其對應的資源不會被釋放,於是,如果在一個程序中,反復建立線程,而線程又默認的退出,則最終線程資源耗盡,進程將不再能建立新的線程。
解決這個問題,有2種方式,系統自動釋放線程資源,或者由另一個線程釋放該線程資源。
注意,在這里,我認為進程運行後,本身,也是一個線程,主線程,主線程和主線程建立的線程共享進程資源。不同於其他線程,在於主線程運行結束後,程序退出,所有程序建立的線程也會退出。
系統自動釋放
如果想在線程結束時,由系統釋放線程資源,則需要設置線程屬性為detach。
代碼上,可以這樣表示:
pthread_t t;
pthread_attr_t a; //線程屬性
pthread_attr_init(&a); //初始化線程屬性
pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED); //設置線程屬性
::pthread_create( &t, &a, GetAndSaveAuthviewSDRStub, (void*)lp); //建立線程
其他線程釋放
另一種方式,則是由另一個線程將該資源釋放。
代碼上,可以這樣表示:
pthread_t t;
::pthread_create( NULL, NULL, GetAndSaveAuthviewSDRStub, (void*)lp);
::pthread_join( t);
::pthread_join( t)等待線程t退出,並釋放t線程所佔用的資源。當然,這里也有個同步的功能,使一個線程等待另一個線程退出,然後才繼續運行。
linux線程執行和windows不同,pthread有兩種狀態joinable狀態和unjoinable狀態,如果線程是joinable狀態,當線程函數自己返回退出時或pthread_exit時都不會釋放線程所佔用堆棧和線程描述符(總計8K多)。只有當你調用了pthread_join之後這些資源才會被釋放。
若是unjoinable狀態的線程,這些資源在線程函數退出時或pthread_exit時自動會被釋放。
unjoinable屬性可以在pthread_create時指定,或在線程創建後在線程中pthread_detach自己,如:pthread_detach(pthread_self()),將狀態改為unjoinable狀態,確保資源的釋放。或者將線程置為joinable,然後適時調用pthread_join.
在程序運行中檢查/proc/ <pid> /maps文件,若看到大概8K左右的很多虛擬內存碎片,基本上可以確認是線程資源泄漏造成的300個線程後pthread_create失敗。
不知是否因為自己,先對要創建的線程做了以下屬性設定,
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
然後又在線程函數中使用
pthread_detach(pthread_self());
兩段代碼作用有沖突。
===============================================================================
pthread_detach(threadid)和pthread_detach(pthread_self())的區別應該是調用他們的線程不同,沒其他區別。
pthread_detach(threadid)函數的功能是使線程ID為threadid的線程處於分離狀態,一旦線程處於分離狀態,該線程終止時底層資源立即被回收;否則終止子線程的狀態會一直保存(佔用系統資源)直到主線程調用pthread_join(threadid,NULL)獲取線程的退出狀態。
通常是主線程使用pthread_create()創建子線程以後,一般可以調用pthread_detach(threadid)分離剛剛創建的子線程,這里的threadid是指子線程的threadid;如此以來,該子線程止時底層資源立即被回收;
被創建的子線程也可以自己分離自己,子線程調用pthread_detach(pthread_self())就是分離自己,因為pthread_self()這個函數返回的就是自己本身的線程ID。
③ 在Linux下怎麼修改當前線程的優先順序
注意:盡量不要修改系統默認優先順序
Thread類與線程優先順序相關的屬性和方法:
MAX_PRIORITY : 線程可以具有最高優先順序
MIN_PRIORITY : 線程可以具有的最低優先順序
NORM_PRIORITY : 分配給線程的默認優先順序
getPriority() : 獲得線程的優先順序
setPriority() : 修改線程的優先順序
java">importjava.util.Scanner;
{
publicstaticThread[]getThreads(){
ThreadGroupgroup=Thread.currentThread().getThreadGroup();
Thread[]threads=newThread[group.activeCount()];
group.enumerate(threads);
System.out.println("線程ID "+"線程名稱 "+"線程優先順序");
for(Threadthread:threads){
System.out.println(thread.getId()+" "+thread.getName()+" "+thread.getPriority());;
}
returnthreads;
}
publicstaticStringinput(){
Scannersc=newScanner(System.in);
Stringstr=sc.nextLine();
returnstr;
}
(Thread[]threads){
System.out.println("請輸入您要修改的線程的ID");
inti=Integer.parseInt(input());
intcount=-1;
for(Threadthread:threads){
if(thread.getId()==i){
System.out.println("請輸入您要修改成的優先順序別:");
intpriroty=Integer.parseInt(input());
thread.setPriority(priroty);
break;
}else{
count++;
}
}
if(count==threads.length-1){
System.out.println("找不到您要的線程");
}
getThreads();
}
publicstaticvoidmain(String[]args){
modifyPriority(getThreads());
}
}
④ C++在linux下怎麼多線程
#ifndefTHREAD_H_
#defineTHREAD_H_
#include<unistd.h>
#include<pthread.h>
classRunnable
{
public:
//運行實體
virtualvoidrun()=0;
};
//線程類
classThread:publicRunnable
{
private:
//線程初始化號
staticintthread_init_number;
//當前線程初始化序號
intcurrent_thread_init_number;
//線程體
Runnable*target;
//當前線程的線程ID
pthread_ttid;
//線程的狀態
intthread_status;
//線程屬性
pthread_attr_tattr;
//線程優先順序
sched_paramparam;
//獲取執行方法的指針
staticvoid*run0(void*pVoid);
//內部執行方法
void*run1();
//獲取線程序號
staticintget_next_thread_num();
public:
//線程的狀態-新建
staticconstintTHREAD_STATUS_NEW=0;
//線程的狀態-正在運行
staticconstintTHREAD_STATUS_RUNNING=1;
//線程的狀態-運行結束
staticconstintTHREAD_STATUS_EXIT=-1;
//構造函數
Thread();
//構造函數
Thread(Runnable*target);
//析構
~Thread();
//線程的運行體
voidrun();
//開始執行線程
boolstart();
//獲取線程狀態
intget_state();
//等待線程直至退出
voidjoin();
//等待線程退出或者超時
voidjoin(unsignedlongmillis_time);
//比較兩個線程時候相同,通過current_thread_init_number判斷
booloperator==(constThread*other_pthread);
//獲取this線程ID
pthread_tget_thread_id();
//獲取當前線程ID
staticpthread_tget_current_thread_id();
//當前線程是否和某個線程相等,通過tid判斷
staticboolis_equals(Thread*iTarget);
//設置線程的類型:綁定/非綁定
voidset_thread_scope(boolisSystem);
//獲取線程的類型:綁定/非綁定
boolget_thread_scope();
//設置線程的優先順序,1-99,其中99為實時,意外的為普通
voidset_thread_priority(intpriority);
//獲取線程的優先順序
intget_thread_priority();
};
intThread::thread_init_number=1;
inlineintThread::get_next_thread_num()
{
returnthread_init_number++;
}
void*Thread::run0(void*pVoid)
{
Thread*p=(Thread*)pVoid;
p->run1();
returnp;
}
void*Thread::run1()
{
thread_status=THREAD_STATUS_RUNNING;
tid=pthread_self();
run();
thread_status=THREAD_STATUS_EXIT;
tid=0;
pthread_exit(NULL);
}
voidThread::run()
{
if(target!=NULL)
{
(*target).run();
}
}
Thread::Thread()
{
tid=0;
thread_status=THREAD_STATUS_NEW;
current_thread_init_number=get_next_thread_num();
pthread_attr_init(&attr);
}
Thread::Thread(Runnable*iTarget)
{
target=iTarget;
tid=0;
thread_status=THREAD_STATUS_NEW;
current_thread_init_number=get_next_thread_num();
pthread_attr_init(&attr);
}
Thread::~Thread()
{
pthread_attr_destroy(&attr);
}
boolThread::start()
{
returnpthread_create(&tid,&attr,run0,this);
}
inlinepthread_tThread::get_current_thread_id()
{
returnpthread_self();
}
inlinepthread_tThread::get_thread_id()
{
returntid;
}
inlineintThread::get_state()
{
returnthread_status;
}
voidThread::join()
{
if(tid>0)
{
pthread_join(tid,NULL);
}
}
voidThread::join(unsignedlongmillis_time)
{
if(tid==0)
{
return;
}
if(millis_time==0)
{
join();
}
else
{
unsignedlongk=0;
while(thread_status!=THREAD_STATUS_EXIT&&k<=millis_time)
{
usleep(100);
k++;
}
}
}
boolThread::operator==(constThread*other_pthread)
{
if(other_pthread==NULL)
{
returnfalse;
}if(current_thread_init_number==(*other_pthread).current_thread_init_number)
{
returntrue;
}
returnfalse;
}
boolThread::is_equals(Thread*iTarget)
{
if(iTarget==NULL)
{
returnfalse;
}
returnpthread_self()==iTarget->tid;
}
voidThread::set_thread_scope(boolisSystem)
{
if(isSystem)
{
pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);
}
else
{
pthread_attr_setscope(&attr,PTHREAD_SCOPE_PROCESS);
}
}
voidThread::set_thread_priority(intpriority)
{
pthread_attr_getschedparam(&attr,¶m);
param.__sched_priority=priority;
pthread_attr_setschedparam(&attr,¶m);
}
intThread::get_thread_priority(){
pthread_attr_getschedparam(&attr,¶m);
returnparam.__sched_priority;
}
#endif/*THREAD_H_*/
⑤ Linux有內核級線程么
需要你的電腦有HDMI
介面才能使用,一般現在賣的筆記本新版的都有,切換就直接在顯卡屬性(XP的在桌面-右鍵-屬性-顯示;WIN7的在桌面-右鍵-屏幕解析度)裡面。你看了界面的內容就知道怎麼操作了。台式機的如果沒有可以添加帶有HDMI介面的顯卡。
⑥ linux下怎麼在等待線程結束中設置超時
多線程退出有三種方式:(1)執行完成後隱式退出;(2)由線程本身顯示調用pthread_exit函數退出;pthread_exit(void*retval);(3)被其他線程用pthread_cance函數終止:pthread_cance(pthread_tthread);用event來實現。在子線程中,在循環內檢測event。while(!e.is_active()){}當退出循環體的時候,自然return返回。這樣子線程會優雅的結束。注意:選用非等待的檢測函數。pthread線程有兩種狀態,joinable(非分離)狀態和detachable(分離)狀態,默認為joinable。joinable:當線程函數自己返回退出或pthread_exit時都不會釋放線程所用資源,包括棧,線程描述符等(有人說有8k多,未經驗證)。detachable:線程結束時會自動釋放資源。Linuxmanpagesaid:Whenajoinablethreadterminates,itsmemoryresources(threaddescriptorandstack)_joinonit.Therefore,pthread_.因此,joinable線程執行完後不使用pthread_join的話就會造成內存泄漏。解決法:1.//創建線程前設置PTHREAD_CREATE_DETACHED屬性pthread_attr_tattr;pthread_tthread;pthread_attr_init(&attr);pthread_attr_setdetachstat(&attr,PTHREAD_CREATE_DETACHED);pthread_create(&thread,&attr,&thread_function,NULL);pthread_attr_destroy(&attr);2.當線程為joinable時,使用pthread_join來獲取線程返回值,並釋放資源。3.當線程為joinable時,也可在線程中調用pthread_detach(pthread_self());來分離自己。
⑦ linux多線程情況下,線程多長時間進行一次切換
linux下線程分為用戶級線程和內核級線程,在內核來看,線程和進程是一樣的,本質上沒有區別
內核提供的是創建進程的介面do_fork()。內核提供了兩個系統調用clone()和fork(),最終都用不同的參數調用do_fork()核內API。當然,要想實現線程,沒有核心對多進程(其實是輕量級進程)共享數據段的支持是不行的,因此,do_fork()提供了很多參數,包括CLONE_VM(共享內存空間)、CLONE_FS(共享文件系統信息)、 CLONE_FILES(共享文件描述符表)、CLONE_SIGHAND(共享信號句柄表)和CLONE_PID(共享進程ID,僅對核內進程,即0號進程有效)。當使用fork系統調用時,內核調用do_fork()不使用任何共享屬性,進程擁有獨立的運行環境,而使用 pthread_create()來創建線程時,則最終設置了所有這些屬性來調用__clone(),而這些參數又全部傳給核內的do_fork(),從而創建的「進程」擁有共享的運行環境,只有棧是獨立的,由__clone()傳入。
具體可以參考<<深入理解Linux內核>>第三版,講的非常詳細
⑧ 如何使用 linux下多線程中條件變數
使用條件變數最大的好處是可以避免忙等。相當與多線程中的信號。
條件變數是線程中的東西就是等待某一條件的發生和信號一樣
以下是說明
,條件變數使我們可以睡眠等待某種條件出現。
條件變數是利用線程間共享的全局變數進行同步的一種機制,主要包括兩個動作:一個線程等待」條件變數的條件成立」而掛起;另一個線程使」條件成立」(給出條件成立信號)。為了防止競爭,條件變數的使用總是和一個互斥鎖結合在一起。
條件變數類型為pthread_cond_t
創建和注銷
條件變數和互斥鎖一樣,都有靜態動態兩種創建方式,靜態方式使用PTHREAD_COND_INITIALIZER常量,如下:
pthread_cond_t cond=PTHREAD_COND_INITIALIZER
動態方式調用pthread_cond_init()函數,API定義如下:
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)
盡管POSIX標准中為條件變數定義了屬性,但在LinuxThreads中沒有實現,因此cond_attr值通常為NULL,且被忽略。
注銷一個條件變數需要調用pthread_cond_destroy(),只有在沒有線程在該條件變數上等待的時候才能注銷這個條件變數,否則返回EBUSY。API定義如下:
int pthread_cond_destroy(pthread_cond_t *cond)
等待和激發
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
等待條件有兩種方式:無條件等待pthread_cond_wait()和計時等待pthread_cond_timedwait(),其中計時等待方式如果在給定時刻前條件沒有滿足,則返回ETIMEOUT,結束等待,其中abstime以與time()系統調用相同意義的絕對時間形式出現,0表示格林尼治時間1970年1月1日0時0分0秒。
使用絕對時間而非相對時間的優點是。如果函數提前返回(很可能因為捕獲了一個信號,)
無論哪種等待方式,都必須和一個互斥鎖配合,以防止多個線程同時請求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的競爭條件(Race Condition)。mutex互斥鎖必須是普通鎖(PTHREAD_MUTEX_TIMED_NP)或者適應鎖(PTHREAD_MUTEX_ADAPTIVE_NP),且在調用pthread_cond_wait()前必須由本線程加鎖(pthread_mutex_lock()),而在更新條件等待隊列以前,mutex保持鎖定狀態,並在線程掛起進入等待前解鎖。在條件滿足從而離開pthread_cond_wait()之前,mutex將被重新加鎖,以與進入pthread_cond_wait()前的加鎖動作對應。
激發條件有兩種形式,pthread_cond_signal()激活一個等待該條件的線程,存在多個等待線程時按入隊順序激活其中一個;而pthread_cond_broadcast()則激活所有等待線程。
其他
pthread_cond_wait()和pthread_cond_timedwait()都被實現為取消點,因此,在該處等待的線程將立即重新運行,在重新鎖定mutex後離開pthread_cond_wait(),然後執行取消動作。也就是說如果pthread_cond_wait()被取消,mutex是保持鎖定狀態的,因而需要定義退出回調函數來為其解鎖。
⑨ linux裡面多線程編程問題
mutex是線程鎖,多個線程運行,當遇到臨界資源,基本上是全局變數時,需要順序的操作這些資源,不能都去操作,就像資料庫裡面的原子操作,所以需要用一個鎖來同步這些線程,讓他們一個一個的來,誰獲得鎖,誰有權操作。
pthread_mutex_init是對鎖進行初始化,一個參數是鎖結構體,一個是屬性,屬性基本為NULL就行。
pthread_mutex_lock用來加鎖,加鎖後,別的線程運行到這個地方就不能繼續運行了,等待解鎖。
pthread_mutex_unlock用來解鎖。
pthread_mutex_destroy用來銷毀鎖。
⑩ linux中線程有哪些屬性
線程的資源是共享的,進程的資源是分開的。多個線程同時訪問一塊資源時一定要注意不能沖突,可以用信號量和鎖的思想來解決反問同一個資源問題。