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中线程有哪些属性
线程的资源是共享的,进程的资源是分开的。多个线程同时访问一块资源时一定要注意不能冲突,可以用信号量和锁的思想来解决反问同一个资源问题。