5、线程(李慧琴课程笔记)

5、线程(李慧琴课程笔记)

概念

一个正在运行的函数

POSIX线程是一套标准,而不是实现。

openmp线程(不太重要,了解即可)

线程表示 pthread_t

ps -ax -L以Linux形式查看进程和线程。PID为进程,LWP为轻量级进程,也就是线程。

**注意:**不能贸然打印pthread_t标识,可能会出错

int pthread_equal(pthread_t t1, pthread_t t2);/*比较两个线程标识,如果相等返回非0,反之返回0*/
pthread_t pthread_self(void);/*返回当前线程标识*/

5.1 sche_yield()函数的作用:

出让调度器

pthread_mutex_unlock(&mut_num);
	sche_yield();/*出让调度器给别的线程,相当于别的线程也可以抢这个互斥所了*/
pthread_mutex_lock(&mut_num);

pthread_mutex_lock()函数不一定只能对应一个pthread_mutex_unlock()函数。

5.2 线程的创建

其实这里有个小技巧,如果说你想传入线程处理函数一个好看一点的不用强转的变量的话,可以考虑用结构体指针的形式,比如你定义一个*P的结构体,那么arg参数直接写P,然后在start_routine这个函数里面直接使用P->函数成员就行了

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);/*成功返回为0,失败返回error number*/
/*pthread_t *thread 这个是回填给你的线程标识,就是你先注册一个pthread_t 类型的线程标识,放到这,然后函数就会给你回填*/
/*const pthread_attr_t *attr 在获取线程标识的时候,给线程标识指定的属性,一般是写NULL,也就是默认属性*/
/*void *(*start_routine)(void *) 传入的函数指针*/
/*void *arg 传入第三个参数,也就是要传入函数的参数*/

线程的调度取决于调度器策略

5.3线程的终止和栈清理

线程终止三种方式

  1. 线程从启动例程返回,返回值就是线程的退出码
  2. 线程可以被同一进程中的其他线程取消
  3. 线程调用pthread_exit()函数
void pthread_exit(void *retval);/*retval返回值可以自己定,但肯定是一个指针*/

int pthread_join(pthread_t thread, void **retval);/*类似于wait()函数,注意thread是变量不是地址*/
/*void **retval若写空则是只收尸,不关心状态*/

栈的清理

void pthread_cleanup_push(void (*routine)(void*), void *arg);/*routine这儿是传入一个函数*/
/*pthread_cleanup_push是钩子函数*/
void pthread_cleanup_pop(int execute);/*当execute为0时只取栈,不调用具体函数*/

pthread_cleanup_push和pthread_cleanup_pop应该是成对出现的,两个其实都是宏定义,在我们预处理文件的时候就可以看出来

5.4线程的取消

int pthread_cancel(pthread_t thread);

线程取消:pthread_cancel

取消有两种状态:允许和不允许

允许取消又分为:异步cancel,推迟cancel(默认)->推迟至cancel点再响应

cancel点:POSIX定义的cancel点,都是可能引发阻塞的系统调用

int pthread_setcancelstate(int state, int *oldstate);/*设置是否允许取消*/
int pthread_setcanceltype(int type, int *oldtype);/*设置取消方式*/
void pthread_testcancel(void);/*本函数什么都不做,就是一个取消点*/
int pthread_detach(pthread_t thread);/*线程分离,就是把一个线程分离出去,不再理会*/

5.5 互斥量

关于互斥量的使用可以看一下李慧琴老师的视频,这里不多做解说了

注意:要注意临界区之内的跳转语句如:continue、break、go to、函数调用,要记得解锁再跳转到临界区外,同时还要注意,并不是说一个lock就只对应一个unclok,需要分情况讨论的。

int pthread_mutex_destory(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);/*mutex就是咱们的互斥量,attr则是索要的属性,后面会有相关的详细解释*/
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*静态初始化互斥量的方式,pthread_mutex_init则是动态初始化方式,动态可能就是位于结构体当中或者需要初始化属性之类的*/
int pthread_mutex_lock(pthread_mutex_t *mutex);/*阻塞的上锁*/
int pthread_mutex_trylock(pthread_mutex_t *mutex);/*非阻塞模式的上锁*/
int pthread_mutex_unlock(pthread_mutex_t *mutex);/*解锁用的*/
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值