Linux系统编程之多线程

多线程:

线程属于进程里面的基本调度单位,每一个进程都拥有自己的main(主线程)。

 

按照调度分为用户级线程和核心级线程

用户级线程作用:解决上下文的切换问题,调度算法和调度过程有用户来决定,

特点:用户级线程在运行时候不需要内核的支持。 缺点:无法发挥内核多处理器的优势。

核心级线程作用:允许不同线程按照同一个调度方式进行运行,能够发挥内核多处理器并发的优势,

实现一对一或者一对多。

 

学习阶段写的是用户级线程。

 

一个进程里面可以有多个线程,

也就是说多个线程控制同一个堆区、常量区和静态区域区域,都是公用一个地址空间。

这时候就会出现一个问题,由于线程共享了进程资源空间和地址,

因此,任何线程对资源操作会对其他线程的操作造成影响。

这时候就需要线程互斥的操作(请看后面的讲解)。

 

当创建线程的那一刻起,所有线程就是同时进行的(线程没有退出的情况下)。

讲个例子:

平常我们写的程序是从上到下运行的,并且只有一条路,遇到函数了,

就会先进函数,执行完了函数的代码,才回来主函数继续往下走,这就是单线程。

多线程就是有多条路,可以同时走多条路。通俗点说就是cpu可以同时运行多个函数(其实一条线程就是一个函数)。

 

创建线程函数:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

void *(*start_routine) (void *), void *arg);

参数:

pthread_t *thread 线程id,指的是要创建的线程的id号

const pthread_attr_t *attr 用来修改线程属性,一般直接给NULL

void *(*start_routine) (void *) 函数指针,一般给自己写的函数的函数名

void *arg 传递给子线程的值

返回值:

成功:返回0

失败:不等于0

当主线程运行结束,所有的线程都会结束,这个时候需要阻塞函数,阻塞主线程保证其他线程正常运行。

主线程阻塞等待:

原型:int pthread_join(pthread_t thread,void **retval)

参数:pthread_t thread ---->线程ID

      void **retval 接收目标线程退出时传出来的参数数据,一般NULL

返回值:成功,返回0

        失败,非0

功能:等待另一线程结束---阻塞等待

 

主线程非阻塞等待:

函数原型:int pthread_detach(pthread_t thread);

函数形参:pthread_t thread -----线程ID

功能:等待线程退出---非阻塞等待 主要作用回收资源

返回值:

成功 0

失败 非0

 

根据需求选择阻塞或者非阻塞。

 

线程退出函数:

原型:void pthread_exit(void *retval)    

参数:void *retval 传递给等待的线程的数据,一般情况直接给NULL

结束当前线程,并传递一个数据给同进程下等待该线程结束的另一个线程(创建他的线程)

return、exit()、pthread_exit()区别:

1.returen 是一个关键字,作用用来结束一个函数,return 不一定能够结束进程或线程

2.exit() 是一个函数,作用是用来结束一个进程,一定会结束进程下面多个线程,以及函数。

3.pthread_exit()是一个函数,作用是用来结束对应的线程,只能结束对应的线程,不能结束对应的进程。

 

 

 

线程互斥锁:

共享资源:多个线程可以同时访问。

临界资源:只可以同时被一个进程或者线程占用。

 

sudo apt-get install manpages-posix-dev安装相关的资源包

默认在man手册第3层 -f找不到

安装相关资源包之后才能查询到

核心:上锁和解锁操作。上锁:占用这个共享资源;解锁:释放占用的共享资源。

1.创建锁: int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

参数:

1).pthread_mutex_t *restrict mutex:自定义锁类型的变量  

2).pthread_mutexattr_t *restrict attr:锁的属性 一般默认属性 给NULL

返回值: 

0: 互斥锁创建成功

失败: 非0

 

2. 上锁:int pthread_mutex_lock(pthread_mutex_t *mutex);阻塞调用     

3. 解锁: int pthread_mutex_unlock(pthread_mutex_t *mutex);   

 

4. 销毁锁:int pthread_mutex_destroy(pthread_mutex_t *mutex);

 

线程互斥的目的是为了让线程有序,并且保护共享资源,最简单的例子就是:主线程打印奇数,子线程打印偶数。watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGlsT25lMTIz,size_20,color_FFFFFF,t_70,g_se,x_16

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值