当前位置: 首页 > wzjs >正文

城乡互动联盟网站建设百度搜索如何去广告

城乡互动联盟网站建设,百度搜索如何去广告,三只松鼠网站怎样做,关于电器网站建设的法律线程 线程的概述 在之前,我们常把进程定义为 程序执行的实例,实际不然,进程实际上只是维护应用程序的各种资源,并不执行什么。真正执行具体任务的是线程。 那为什么之前直接执行a.out的时候,没有这种感受呢&#xf…

线程

线程的概述

在之前,我们常把进程定义为 程序执行的实例,实际不然,进程实际上只是维护应用程序的各种资源,并不执行什么。真正执行具体任务的是线程。

那为什么之前直接执行a.out的时候,没有这种感受呢?

那是因为每一个进程中都会有一个主线程,我们默认执行的就是这个主线程。

线程创建比进程简单

进程通过返回值确定 是哪块进程的代码。

线程不需要,创建一个线程,比较简单,像回调函数一样,调用线程创建函数,在对应函数体中 操作这一线程即可。

从这往下的概述部分 重点(理解背诵)

进程是系统分配资源的基本单位,线程是CPU执行基本调度的基本单位

比如 如果线程是具体某个人,那么进程就是指部门

线程可以看作一个轻量级的进程(LWP:light weight process),在Linux环境下线程的本质仍是进程

进程 必须至少包含一个线程

线程依赖于进程,线程共享进程的资源,线程的系统资源有(计数器,一组寄存器和栈)

进程结束 当前进程的所有线程 都将立即结束

Linux内核是不区分进程和线程的,只有在用户层面上进行区分。所以,进程所有操作函数pthread*是库函数,而并非系统调用

线程共享资源

  1. 文件描述符
  2. 每种信号的处理方式
  3. 当前工作目录
  4. 用户ID和组ID 内存地址空间

线程非共享资源

  1. 线程id
  2. 处理器现场和栈指针
  3. 独立的栈空间
  4. errno变量
  5. 信号屏蔽字
  6. 调度优先级

线程被CPU调度,因此线程中有调度优先级,且线程间不共享

查看指定进程的线程号的命令:ps -Lf pid(进程号)

线程的API

API介绍用的代码 较简短的代码我用图片展示。

只要看到了pthread.h 头文件,我们在编译的时候就需要加上 -lpthread

pthread_t 是无符号长整型

1、查看线程号

#include <pthread.h>

pthread_t pthread_self(void);

功能:

        查看线程号

参数:

        无参

返回值:

        调用该函数的线程 的 线程ID

代码演示

代码运行结果

线程ID(通过pthread_self得到) 和 IPW(轻量级进程)的区别

大家看这张图,可以看到这两个值有明显的区别

在Linux中,线程就是LWP(轻量级进程),全局唯一,由操作系统内核分配,用于系统调度和资源管理。

线程ID呢仅在同一进程内有效,是抽象标识符。由 pthread 库在进程内维护。

2、创建线程

#include <pthread.h>

int pthread_create(pthread_t *thread,

                                const pthread_attr_t *attr,

                                void *(*start_routine) (void *),

                                void *arg);

功能:

        创建一个线程

参数:

        thread:线程标识符地址

        attr:线程属性结构体地址,通常设置为NULL

                属性这个参数,我们现在填写NULL,下面我会详细说一下这个参数。

        start_routine:线程函数的入口地址

        arg:传递给线程函数的参数

返回值:

        成功:0

        失败:非0

代码演示 案例1

注意这里主进程一定要阻塞,因为进程结束,线程也会关闭

代码运行结果

案例二 创建进程,每个线程有自己的线程函数

代码运行结果是一样的,大家只要知道能够这样用就可以了。

3、回收线程函数

函数介绍

功能:

        等待线程结束(此函数会阻塞),并回收线程资源。如果线程已结束,那么该函数会立即返回。

参数:

        thread:被等待的进程的进程ID

        retval:用来存储线程退出状态的指针的地址

        这里细说一下:retval的返回值类型我们可以看到是void **,这个变量需要用户创建,用来存储创建函数 线程执行函数的 返回值,返回值时void*类型。由于我们要得到它,就要提前创建一个void *的变量,再通过函数修改我们创建的变量为返回值的内容,由于是函数内部要函数外部的变量的值,因此需要传递所创建void *的变量的地址,因此时void **类型。

返回值:

        成功:0

        失败:非0

代码演示

代码运行结果

注意

由于带阻塞,因此有顺序,如下面这种情况

先等待tid1结束,回收tid1后,才会回收tid2

不管谁先结束,都是先1 后2

进程分离

创建好线程后,当多个任务同时进行,用上面的方法,会阻塞线程的释放,导致资源浪费(长时间不适用却霸占内存),因此这里 我们就将其分离出去,把释放工作交给系统,系统发现它结束,就会释放

由于它的归属权已经归于系统,此时我们就不可以再对它使用join

注意这里的分离,并不是该线程不依赖于进程,而是将 释放线程独立资源 的权限交给了系统,进程还是依赖与进程的,依旧共享进程的空间

函数介绍

#include <pthread.h>

int pthread_detach(pthread_t thread);

功能:

        使调用线程的独立资源回收工作与当前进程分离

参数:

        thread:线程ID

返回值:

        成功:0

        失败:非零

代码演示 主线程和子线程

本代码将实现 主线程和子线程 一起运行,并且利用主线程的正常工作,来验证pthread_detach的不阻塞的特性

代码运行结果

4、线程的取消和退出

        注意要退出线程 一定不要调用exit或者_exit 这两个是退出进程的函数,如果调用这个在线程中知道你的进程是什么,它会将进程退出,进程退出会导致所有的线程退出,那么我们该怎么让单个线程退出呢?

1、线程的退出(自杀)

#include <pthread.h>

void pthread_exit(void *retval);

函数功能:

        退出调用线程。一个进程中的多个线程是共享该进程的数据段的,因此通常线程退出后,所占用的资源并不会释放。

参数:

        retval:存储线程退出状态的指针(return后的数据)

返回值:

        无

2、线程的取消(他杀)

取消本线程,也可以取消当前进程的其他线程

#include <pthread.h>

int pthread_cancel(pthread_t thread);

功能:

        退出调用线程。一个进程中的多个线程是共享该进程的数据段的,因此通常线程退出后,所占用的资源并不会释放。

参数:

        thread:目标线程ID

返回值:

        成功:0

        失败:出错编号

注意

        杀死线程也不是立刻就能完成,必须要到达取消点

        取消点:是线程检查是否被取消,并按请求进行动作的一个位置。通常是一些系统调用

代码演示:

代码功能:子线程1实现5s后自杀,子线程2在7s时杀死子线程3,子线程2在10s时杀死自己。

这里我们会与遇到一个问题:当我们在线程2 中,我们首先需要传入本线程的名字(线程2),还需要传入子线程3的线程ID,我们该如何实现传两个参数呢?

答案在代码中,大家自己查看。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>//传递两个参数的办法就是借助结构体,将线程名和ID作为结构体成员后,将结构体传入 线程调用函数 中即可
//并且如果要实现tid3的修改同步到结构体内,需要传递tid3的指针类型
typedef struct dataDouble
{char name[32];pthread_t *id;
}DATA;//线程调用函数声明
void *my_fun1(void *arg);
void *my_fun2(void *arg);
void *my_fun3(void *arg);
int main(int argc, char const *argv[])
{//创建线程ID遍历(存放线程ID)pthread_t tid1,tid2,tid3;DATA *tid2_data = (DATA *)calloc(1,sizeof(DATA));tid2_data->id = &tid3;strcpy(tid2_data->name,"子进程2");//创建线程pthread_create(&tid1,NULL,my_fun1,(void *)"子线程1");pthread_create(&tid2,NULL,my_fun2,(void *)tid2_data);pthread_create(&tid3,NULL,my_fun3,(void *)"子线程3");//释放线程pthread_detach(tid1);pthread_detach(tid2);pthread_detach(tid3);//阻塞进程while(1);//释放结构体申请空间,一定要在全部线程结束之后free(tid2_data);return 0;
}
//线程调用函数体实现
void *my_fun1(void *arg)//线程1 在5s的时候自杀
{int i = 0;while(1){sleep(1);printf("----%s的运行时间为:%d\n",(char *)arg,++i);if(i == 5){pthread_exit(NULL);}}
}
void *my_fun2(void *arg)//线程2 在7s的时候杀死线程3,在10s的时候自杀(使用cancel)
{DATA data = *(DATA *)arg;int i = 0;while(1){sleep(1);printf("--------%s的运行时间为:%d\n",data.name,++i);if(i == 7){pthread_cancel(*data.id);}if(i == 10){pthread_cancel(pthread_self());}}
}
void *my_fun3(void *arg)
{int i = 0;while(1){sleep(1);printf("------------%s的运行时间为:%d\n",(char *)arg,++i);}
}

代码运行结果

结束

代码重在练习!

代码重在练习!

代码重在练习!

今天的分享就到此结束了,希望对你有所帮助,如果你喜欢我的分享,请点赞收藏夹关注,谢谢大家!!!

下篇介绍:线程的属性介绍,线程池的简述,多线程的建立

http://www.dtcms.com/wzjs/205822.html

相关文章:

  • 一级a做爰片_相关网站微信小程序开发费用一览表
  • stm32做网站服务器百度官网下载安装到桌面上
  • 瓯北网站建设搜索seo优化托管
  • 南京华典建设有限公司网站爱站网长尾关键词挖掘查询工具
  • 网站做英文版有用吗自动点击器app
  • 禹城有做网站智能网站排名优化
  • 佛山网站建设明细今日头条官网登录入口
  • 网站建设与管理拼音泰州seo推广
  • 南昌seo关键词网站seo诊断报告
  • 专业外贸网站济南网站建设方案
  • 上海网站建设找哪家网站数据查询
  • 网站建设里怎么写文章seo超级外链发布
  • 用ip的网站要备案吗网络营销和网站推广的区别
  • sap.net怎么做网站山东seo网页优化外包
  • 自学ui设计需要哪些资料seo服务销售招聘
  • 怎样免费做书画网站百度首页 百度一下
  • 动态网站开发项目实训报告深圳优化公司样高粱seo
  • 郑州网站建设公司招聘百度文库网页版登录入口
  • 对做网站公司的疑问视频外链工具
  • 建造网站需要多少钱有没有免费推广平台
  • 设计上海网站建设友情链接联盟
  • 做网站时怎么选择数据库类型谷歌排名
  • 做网站698靠谱吗什么推广方法是有效果的
  • 杭州网站设计建设公司广告引流推广平台
  • 自己开网站能赚钱吗网站优化就是搜索引擎优化
  • 凡科二级网站怎么做运营商推广5g技术
  • 武汉做网站哪个公司好seo工具是什么意思
  • 用c 怎么做网站系统网络视频营销策略有哪些
  • 自建商城网站用什么技术好营销策划的重要性
  • 用dw做网站图片的基本尺寸天津关键词排名提升