线程的控制与分离

线程的控制

  1. 线程的创建:

    线程创建函数:int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine(void*),void *arg);

    返回值:成功返回0,失败返回错误号。

    在一个线程中调用pthread_create()创建新的线程后,当前线程从pthread_create()返回继续往下执行,而新的线程所执行的代码由我们传给pthread_create()的函数指针star_routine决定。pthread_create成功返回后,新创建的线程id被填写到thread参数所指向的内存单元。线程id的类型是thread_t,它只在当前进程中保证是唯一的,在不同的系统中thread_t这个类型有不同的实现,它可能是一个整数值,也可能是一个结构体,也可能是一个地址,用pthread_self()可获得当前线程id。

    如果任意一个线程调用了exit或_exit,则整个进程的所有线程都终止。

  2. 线程的终止:

    有以下三种方法终止线程:

从线程函数return,这种方法对主线程不适用,从main函数return相当于调用exit;

一个线程可以调用pthread_cancel终止统一进程中的另一个线程;

程可以调用pthread_exit终自己;

下面我们看一段代码,看看这3中方法的区别:

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

#include <sys/types.h>

void *thread1(void *arg)

{

printf("thread 1 returning....\n");

return (void*)1;

}

void *thread2(void *arg)

{

printf("thread 1 exiting....\n");

pthread_exit((void*)2);

}

void *thread3(void *arg)

{

while(1)

{

printf("thread 3 is runing,wait to bu cancel...\n");

sleep(1);

}

return NULL;

}

int main()

{

pthread_t tid;

void *val;

pthread_create(&tid,NULL,thread1,NULL);

pthread_join(tid,&val);

printf("thread return,thread id is:%u,return code is:%d\n",tid,(int)val);

pthread_create(&tid,NULL,thread2,NULL);

pthread_join(tid,&val);

printf("thread exit,thread id is:%u,exit code is:%d\n",tid,(int)val);

pthread_create(&tid,NULL,thread3,NULL);

sleep(3);

pthread_cancel(tid);

pthread_join(tid,&val);

printf("thread return,thread id is:%u,return code is:%d\n",tid,(int)val);

return 0;

}

运行结果如下:

一般情况下,线程终止后,其状态一直保留到其他线程调用pthread_join获取它的状态为止,但是线程也可以被置为detach状态,这样的线程一旦终止,就立刻回收它所占有的所有资源,而不保留终止状态,不能对一个处于detach状态的线程调用pthread_join,这样的调用将返回EINVAL,对一个尚未detach的线程调用pthread_join或pthread_detach都可以把该线程置为detach状态。也就是说不能对一个线程调用两次pthread_join 或者已经对一个线程调用了pthread_detach,就不能再调用pthread_join了。

线程分离

在任何一个时间点上,线程是可结合的或者是可分离的,一个可结合的线程能够被其他线程收回其资源和杀死,在被其他线程收回之前,它的存储资源是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,他的存储器资源在它终止时由系统自动释放。

默认情况下,线程被创建成可结合的,为了避免存储器泄露,每个可结合线程要么被显示的回收,要么调用pthread_detach函数被分离。

由于调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞,我们并不希望如此。我们这时可以在子线程代码中加入pthread_detach(pthread_self())或者父线程调用pthread_detach(tid).这将子线程的状态设置为分离的,该线程运行结束后会自动释放所有资源。

下面我们看一段代码:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

#include <sys/types.h>

void *thread(void *arg)

{

pthread_detach(pthread_self());

printf("thread 1 returning....\n");

return NULL;

}

int main()

{

pthread_t tid;

int ret=pthread_create(&tid,NULL,thread,NULL);

if(ret!=0)

{

printf("create thread error,info is :%s\n",strerror(ret));

}

sleep(1);

if(0==pthread_join(tid,NULL))

{

printf("thread wait success\n");

}

else

{

printf("thread wait failed\n");

}

return 0;

}

运行结果:

从结果可以看到,我们在子线程里面用了pthread_detach,在主线程里面又用了pthread_join,所以会wait failed。

时间: 2024-12-15 07:14:06

线程的控制与分离的相关文章

Linux之线程:控制与分离

之前我一直都提到的是进程,现在多了一个线程的概念,从字面意思来看,线程应该比进程小.嘿嘿. 其实操作系统刚开始的时候,提出进程概念后,操作系统一直都是以进程作为独立运行的基本单位,然后有人感觉了,这不对呀,进程之间的中断转换太浪费了,并且用户态到核心态的切换也有点麻烦,所以在80年代中期,人们又提出了毕竟更小的独立运行的基本单位咯--线程,用来提高系统内存程序的并发执行程度.所以线程就这么出现了. 那,什么是线程呢? 其实简单来说,线程就是进程中的执行分流,从操作系统内部来说其实就是一个指令序列

Linux下线程的控制与分离

一.线程的概念: 线程是运行在进程地址空间的,是进程的执行分流.它是执行进程内部的一个代码片段为了让进程更好的完成.也可以说,进程是承担系统资源的实体,而线程进程运行调度的基本单位. 由于同一进程的多个线程共享同一地址空间,因此Text Segment.Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境: 1. 文件描述符表 2. 每种信号的处理方式(SIG_IGN.SIG_DFL或者

线程的控制和分离

线程的概念:线程是运行在进程内的一个基本执行流,和进程共享地址空间及资源(类似于父子进程共享地址空间),但每个也有自己的私有资源. 进程强调独占性 每个进程都有它独立的地址空间,包括Text Segment.Data Segment等 线程强调共享性 线程的共享资源: 1.进程代码段 2.进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯) 3.进程打开的文件描述符 4.信号的处理器 5.进程的当前目录和进程用户ID与进程组ID 线程的私有资源:(线程实现并发性)       1

Linux - 线程属性控制

线程属性 属性值不能直接设置,须使用相关函数进行操作 初始化函数为pthread_attr_init,该函数必须在pthread_create函数之前调用 typedef struct{ int detachstate; // 线程的分离状态 int scope; // 线程绑定状态 int schedpolicy; // 线程调度策略 struct sched_param schedparam; // 线程的调度参数 int inheritsched; //线程的继承性 size_t guar

Linux--线程的控制与分离

一.线程的概念 线程是进程内部的一个基本执行流,是系统调度的一个实体.进程具有独占性,线程具有共享性.各线程共享进程的文件描述符.信号处理的方式.当前的工作目录.用户id(uid)和组id(gid).但是有些资源线程是私有的,比如线程id.栈空间.上下文(包括各种寄存器的值.程序计数器和栈指针).占空间.信号屏蔽字.调度优先级.就好比进程如果是一个家庭的话,线程就是这个家庭的成员,每个家庭的成员都有一个公共的空间(餐厅,客厅).当然每个家庭成员也有自己的私人空间了. 二.线程的控制 创建线程和终

java中线程的控制

线程的控制: Java中的线程支持提供了一些便捷的工具方法,通过这些便捷的工作方法可以更好的控制线程的执行. 一.join线程: Thread提供了让一个线程等待另一个线程完成的方法——join()方法.当某个程序执行流中调用其他线程的join方法时,调用线程将被阻塞,直到被join方法加入的join线程执行完为止. Join()方法有如下3种重载形式: 1.join():等待被join的线程执行完成. 2.join(long millis):等待被join的线程的时间最长为millis 毫秒,

Java多线程之线程的控制

Java多线程之线程的控制 线程中的7 种非常重要的状态:  初始New.可运行Runnable.运行Running.阻塞Blocked.锁池lock_pool.等待队列wait_pool.结束Dead 如果将"锁池"和"等待队列"都看成是"阻塞"状态的特殊情况,那么可以将线程归纳为5个状态: 新建,就绪,运行,阻塞,死亡. ┌--------------------< 阻塞 ↓                    (1)(2)(3)  

线程控制与分离

线程: 在一个进程的地址空间中执行多个线程 ---- 强调共享  线程是进程中的一个实体. 线程私有: 线程id 上下文信息 (包括各种寄存器的值.程序计数器和栈指针) (私有)栈空间    errno变量    信号屏蔽字    调度优先级 此时:POSIX标准   编译时  加上 -lpthread 线程与进程的区别: 1.进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位: 线程是进程的一个实体. 2.进程 强调 独占,线程 强调 共享

Java多线程开发系列之四:玩转多线程(线程的控制2)

在上节的线程控制(详情点击这里)中,我们讲解了线程的等待join().守护线程.本节我们将会把剩下的线程控制内容一并讲完,主要内容有线程的睡眠.让步.优先级.挂起和恢复.停止等. 废话不多说,我们直接进入正题:  3.线程睡眠  sleep() 所有介绍多线程开发的学习案例中,基本都有用到这个方法,这个方法的意思就是睡眠(是真的,请相信我...).好吧,如果你觉得不够具体,可以认为是让当前线程暂停一下,当前线程随之进入阻塞状态,当睡眠时间结束后,当前线程重新进入就绪状态,开始新一轮的抢占计划!