多线程基础(系统编程四)

18 篇文章 0 订阅
16 篇文章 0 订阅

一、多线程

1. 线程和进程的联系和区别

联系:

第一个:线程从进程资源中分割一部分创建出来的

第二个:线程和进程都是能实现多任务的并发执行,实际开发中还是用线程会多一点

区别:

第一个:线程创建的时候不需要消耗额外的系统资源

进程创建的时候需要消耗额外的系统资源

线程的特点:

创建了多个线程,多个线程执行顺序是随机的

理论概念:

主线程和子线程: 调用creat函数创建子线程的进程称为主线程,被创建的线程称为子线程

孤儿线程: 主线程创建的子线程,如果主线程不回收,子线程就变成了孤儿线程

2. 线程有关的接口函数

(一)创建线程

#include<pthread.h>

int pthread_create( pthread_t *id,   const pthread_attr_t *attr ,  void*(*start_rtn)(void*),  void *arg );
参数:id --- 存放线程的id
     attr --- 重点,线程的属性,一般设置为NULL,表示使用系统默认的属性
     void*  (*start_rtn)(void*) --- 重点,函数指针,线程的任务函数,线程需要完成的任务就靠这个函数指针指向的函数去实现
     arg --- 传递给start_rtn的参数(线程跟主函数之间传递参数)

注意:只要你的代码中使用了跟线程有关的函数,编译的时候必须链接线程库

gcc hello.c -o hello -pthread

gcc hello.c -o hello -lpthread 都正确

(二)线程的退出和回收

(1)线程的退出
#include<pthread.h>

void pthread_exit(void *retval);
参数:retval --- 存放线程退出时候的信息
(2)线程的回收(阻塞主函数,等待子线程的退出)
#include<pthread.h>

int pthread_join(pthread_t thread, void **retval);
参数:thread --- 你要回收的那个线程的id号
     retval --- 用来存放是 pthread_exit函数中参数的地址(存放线程退出时的信息)

(三)线程的取消(强行干掉线程)

#include<pthread.h>

int pthread_cancel(pthread_t thread);
参数:thread --- 线程id
(1)设置线程的取消状态
#include<pthread.h>

int pthread_setcancelstate(int state, int *oldstate);  //设置线程取消状态

线程的取消状态有两种: 可以取消和不可以取消

参数:state --- PTHREAD_CANCEL_ENABLE  //能取消,线程默认就是能被取消
               PTHREAD_CANCEL_DISABLE //不能取消
     oldstate --- 存放线程原本的取消状态
(2)设置线程的取消类型
#include<pthread.h>

int pthread_setcanceltype(int type, int *oldtype);  //设置线程取消类型(了解)

线程的取消类型有两种:

立即取消: 只要你调用了pthread_cancel()函数,线程就立马退出

延时取消: 只要你调用了pthread_cancel()函数,线程不会立即退出,会继续执行直到遇到下一个取消点才退出

取消点: linux系统中定义的一系列函数,这些函数就是线程的取消点函数 man 7 pthreads查看到系统中所有的取消点函数

参数:type --- PTHREAD_CANCEL_DEFERRED  //延时取消
              PTHREAD_CANCEL_ASYNCHRONOUS  //立即取消
     oldtype --- 存放线程原本的取消类型

(四)线程的属性

(1) 线程属性结构如下:
typedef struct
{
  int	detachstate;     线程的分离状态
  int	schedpolicy;   线程调度策略
  struct sched_param	schedparam;   线程的调度参数
  int	inheritsched;    线程的继承性
  int	scope;          线程的作用域
  size_t	guardsize; 线程栈末尾的警戒缓冲区大小
  int	stackaddr_set;
  void *	stackaddr;      线程栈的位置
  size_t	stacksize;       线程栈的大小
}pthread_attr_t;

规律: linux中已经把这个结构体中所有的属性设置获取都封装成了函数

设置属性: pthread_attr_setxxxxx

获取属性: pthread_attr_getxxxxx

比如:分离属性分为两种,一种可分离,另一种不可分离

可分离: 线程退出之后不需要主函数去回收,线程自己回收自己,线程可以自生自灭(主函数想回收也回收不了并且pthread_join函数也不会阻塞了)

不可分离: 线程退出之后,需要主函数去回收(线程默认就是不可分离)

(2)设置线程属性的套路

①定义线程属性变量并初始化

#include <pthread.h>

pthread_attr_t  myattr;//定义一个线程属性结构体

pthread_attr_init(&myattr);  //初始化线程的属性
参数:myattr --- 把定义的线程属性结构体作为地址传入

②调用对应的属性设置函数去设置属性

比如:设置分离属性

#include <pthread.h>

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
参数:detachstate --- PTHREAD_CREATE_DETACHED    可以分离
                     PTHREAD_CREATE_JOINABLE      不可分离

③调用线程的创建函数,并把属性作为参数传递过来

#include <pthread.h>

pthread_create(&id,&myattr,);//myattr对应线程创建函数中的参数attr

④销毁线程的属性

#include <pthread.h>

int pthread_attr_destroy(pthread_attr_t *attr);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java.L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值