一、线程控制

1、线程:线程是资源调度的基本单位,线程是进程内部的一个执行流,在进程的地址空间内运行。在Linux 下没有真正意义上的线程,线程是用进程模拟的,又被称为轻量级进程。

2、由于同⼀一进程的多个线程共享同⼀一地址空间。因此Text Segment、Data Segment都是共享的,除此之外,各线程还共享以下进程资源和环境:

1). ⽂文件描述符表;

2). 每种信号的处理⽅方式(SIG_IGN、SIG_DFL或者⾃自定义的信号处理函数);

3). 当前⼯工作⽬目录;

4). ⽤用户id和组id;

但有些资源是每个线程各有一份的:

1).线程id

2). 上下⽂文,包括各种寄存器的值、程序计数器和栈指针

3). 栈空间

4). errno变量

5). 信号屏蔽字

6). 调度优先级

3、线程创建:

函数原型:int pthread_create(pthread_t thread, const pthread_attr_t *attr, void (start_routine) (void ), void *arg);

创建成功:返回0 ;创建失败:返回错误码,可将错误码通过strerror()转换为字符串描述。

参数1:线程id地址(只在用户区有效)。

参数2:线程属性,一般设置为NULL。

参数3:函数指针,指向线程函数。

参数4:线程函数的参数。

创建结果:

3、终⽌止线程

如果需要只终⽌止某个线程⽽而不终⽌止整个进程,可以有三种⽅方法:

1). 从线程函数return。这种⽅方法对主线程不适⽤用,从main函数return相当于调⽤用exit。

2). ⼀一个线程可以调⽤用pthread_cancel终⽌止同⼀一进程中的另⼀一个线程,⽤用pthread_cancel终⽌止⼀一个线程分同步和异步两种情况。

3). 线程可以调⽤用pthread_exit终⽌止⾃自⼰己。

4、线程等待

返回值:成功返回0,失败返回错误号
    调⽤用该函数的线程将挂起等待,直到id为thread的线程终⽌止。thread线程以不同的⽅方法终⽌止,通过pthread_join得到的终⽌止状态是不同的,总结如下:
    1. 如果thread线程通过return返回,value_ptr所指向的单元⾥里存放的是thread线程函数的返回值。
    2. 如果thread线程被别的线程调⽤用pthread_cancel异常终掉,value_ptr所指向的单元⾥里存放的是常数PTHREAD_CANCELED。
    3. 如果thread线程是⾃自⼰己调⽤用pthread_exit终⽌止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。 如果对thread线程的终⽌止状态不感兴趣,可以      传NULL给value_ptr参数

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

void* thread1(void* arg)
{

printf("new thread1\n");
    return (void*)123;
}
void* thread2(void* arg)
{
    while(1)
    {
        printf("new thread2\n");
        sleep(1);
        pthread_exit((void*)456);
    }
    
}
void* thread3(void* arg)//被其他线程cancel
{
    while(1)
    {
        printf("new thread3\n");
        sleep(1);
    }
    return NULL;
}

int main()
{
    pthread_t tid1,tid2,tid3,tid4;
    void* val = NULL;
    pthread_create(&tid1,NULL,thread1,NULL);
    pthread_create(&tid2,NULL,thread2,NULL);
    pthread_create(&tid3,NULL,thread3,NULL);
    pthread_create(&tid4,NULL,thread4,NULL);
    
    pthread_join(tid1,&val);
    printf("thread1 is quit,thread1 id is %lu, exit code:%d\n",tid1,(int)val);
    pthread_join(tid2,&val);
    printf("thread2 is quit,thread2 id is %lu, exit code:%d\n",tid2,(int)val);

pthread_cancel(tid3);
    pthread_join(tid3,&val);
    printf("thread3 is quit,thread3 id is %lu, exit code:%d\n",tid3,(int)val);

return 0;
}

运行结果:

注:

可见在Linux的pthread库中常数PTHREAD_CANCELED的值是-1。可以在头⽂文件pthread.h中找到它的定义。

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

二、分离线程

在任何⼀一个时间点上,线程是可结合的(joinable)或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,

它的存储器资源(例如栈)是不释放的。相反,⼀一个分离的线程是不能被其他线程回收或杀死的,它的存储器 资源在它终⽌止时由系统⾃自动释放。

1、默认情况下,线程被创建成可结合的。为了避免存储器泄漏,每个可结合线程都应该要么被显⽰示地回收,即调⽤用pthread_join;要么通过调⽤用pthread_detach

函数被分离。如果⼀一个可结合线程结束运⾏行但没有被join,则它的状态类似于进程中的Zombie Process,即还有⼀一部分资源没有被回收,所以创建线程者应该调用

pthread_join来等待线程运⾏行结束,并可得到线程的退出代码,回收其资源。

2、 由于调⽤用pthread_join后,如果该线程没有运⾏行结束,调⽤用者会被阻塞,在有些情况下我们并不希望如此。例如,在Web服务器中当主线程为每个新来的连接

请求创建⼀一个⼦子线程进⾏行处理的时候,主线程并不希望因为调⽤用pthread_join⽽而阻塞(因为还要继续处理之后到来的连接请求),这时可以在⼦子线程中加入

代码 pthread_detach(pthread_self());

或者⽗父线程调⽤用pthread_detach(thread_id)(⾮非阻塞,可⽴立即返回)

这将该⼦子线程的状态设置为分离的(detached),如此一来,该线程运⾏行结束后会⾃自动释放所有资源。

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

void* thread(void *_arg)
{
    //pthread_detach(pthread_self());//线程自已设置自已的可分离属性
printf("new thread is run...\n");
    return (void*)1;
}

int main()
{
    pthread_t tid;
    int ret = pthread_create(&tid,NULL,thread,NULL);
    if(ret != 0)
    {
        printf("thread create failed,error code:%s\n",strerror(ret));
return ret;
    }
    sleep(1);
    pthread_detach(tid);//将子线程属性设置为分离(非阻塞,可立即返回)
    void* val = NULL;
    if((pthread_join(tid, &val) != 0))
    {
        printf("thread wait failed\n");
ret = 1;
}
    else
    {
        printf("thread id : %u ,exit code : %d\n",tid, (int)val);
ret = 0; 
    }
    return ret;
}

运行结果:

线程的控制(创建、等待、终止)、分离线程相关推荐

  1. java 父线程_Java父线程(或是主线程)等待所有子线程退出的实例

    导读热词 实例如下: static void testLock1(){ final AtomicInteger waitCount = new AtomicInteger(30000); final ...

  2. python结束线程_2018-01-02 如何优雅地终止python线程

    前言 · 零 我们知道,在python里面要终止一个线程,常规的做法就是设置/检查 --->标志或者锁方式来实现的. 这种方式好不好呢? 应该是不大好的!因为在所有的程序语言里面,突然地终止一个 ...

  3. java主线程控制子线程_CountDownLatch控制主线程等子线程执行完--Java多线程

    1.[代码]CountDownLatch控制主线程等子线程执行完--Java多线程 package com.sihuatech.common; import java.util.concurrent. ...

  4. java线程池怎么创建_java中的线程池,如何创建?

    Java中的线程池它是线程的容器,或者(换句话说,它是具有执行任务能力的线程的集合). 我们可以使用ThreadPool框架来定位(或实现)线程池. 线程池可以包含多个线程.每当我们执行任何任务时,线 ...

  5. 【Linux】进程控制(创建、终止、等待)

    环境:centos7.6,腾讯云服务器 Linux文章都放在了专栏:[Linux]欢迎支持订阅 相关文章推荐: [Linux]冯.诺依曼体系结构与操作系统 [Linux]进程理解与学习Ⅰ-进程概念 [ ...

  6. 进程控制——创建,终止

    目录 1.进程的创建 fork函数初识 fork函数返回值 写时拷贝 fork常规用法 2.进程终止 进程退出场景 进程常见退出方法 进程退出返回值的意义: 1.进程的创建 fork函数初识 在lin ...

  7. 【C++ 语言】线程 ( 线程创建方法 | 线程标识符 | 线程属性 | 线程属性初始化 | 线程属性销毁 | 分离线程 | 线程调度策略 | 线程优先级 | 线程等待 )

    文章目录 I 线程创建方法 II 线程执行函数 III 线程标识符 IV 线程属性 V 线程属性 1 ( 分离线程 | 非分离线程 ) VI 线程属性 2 ( 线程调度策略 ) VII 线程属性 3 ...

  8. Linux系统编程----15(线程与进程函数之间的对比,线程属性及其函数,线程属性控制流程,线程使用注意事项,线程库)

    对比 进程 线程 fork pthread_create exit (10) pthread_exit (void *) wait (int *) pthread_join (,void **)阻塞 ...

  9. Executors创建的4种线程池的使用

    Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFi ...

  10. 10月13日学习内容整理:线程,创建线程(threading模块),守护线程,GIL(全局解释器互斥锁)...

    一.线程 1.概念:一条流水线的工作过程 2.和进程的区别和关系 (1)关系 >进程是资源单位,线程是执行单位,cpu真正执行的是线程 >一个进程至少有一个线程 >多线程针对的是一个 ...

最新文章

  1. 结构光测距相位差_ROHM确立新型VCSEL模块技术 有助于提高测距精度
  2. Java项目:实现个人博客系统(java+springboot+mybatis+redis+vue+elementui+Mysql)
  3. nodejs http.get 方法可以 request 不行
  4. Azure实践之automation自动整理资产信息
  5. reverse-for-the-holy-grail-350逆向寒假生涯(23/100)
  6. PostgreSQL failed IANA tz database BUG修复
  7. C#编程(四十八)----------列表
  8. sql 分组求和_数据仓库工具–Hive(归纳笔记第六部分:SQL练习)
  9. USACO SEC.1.3 No.1 Mixing Milk
  10. Spring的IOC原理(通俗解释)
  11. Android之事件总线EventBus详解
  12. 96.2. Yum 安装
  13. ps怎么把图片背景变透明_ps怎么添加背景?ps怎么添加背景图?
  14. 算法-罗马数字转成整数(leetcode13)
  15. 拓端tecdat|电商平台数据解锁网红零食销量密码
  16. OpenLayers自定义圆锥投影中国地图
  17. oppo手机显示服务器连接错误,OPPO手机连不上wifi怎么办?OPPO连不上wifi的四种解决方法...
  18. Codeforces 437B 437C
  19. 服务器装系统出现命令提示符,怎么通过cmd命令提示符重装系统?具体怎么操作?...
  20. java rar解压

热门文章

  1. JDK8下载|JDK1.8下载可选择window版和linux版
  2. Lisenter笔记
  3. 牛客网Java刷题知识点之关键字static、static成员变量、static成员方法、static代码块和static内部类...
  4. sql server 保留小数,向上保留指定位数的小数,仅记录,勿看。
  5. iOS - Core Animation 核心动画
  6. ==与equal在java中应用的感悟
  7. 1023:坑爹的黑店
  8. 新浪微博之XSS蠕虫脚本源码讲解
  9. 绘图基础语法与常用参数
  10. Vue Axios的配置 (高仿饿了么)