【网络编程】多线程编程--线程基础

文章目录

  • 一、创建线程与结束线程
    • 1.1、pthread_create
    • 1.2、pthread_exit
    • 1.3、pthread_join
    • 1.4、pthread_cancel
  • 二、线程属性


  线程是程序中完成一个独立任务的完整执行序列,根据运行环境以及调度者的身份,可以分为内核线程以及用户线程。

  • 内核线程,运行在内核空间,由内核来调度,有的系统上也称为LWP(轻量级进程)
  • 用户线程,运行在用户空间,由线程库来调度

  内核线程相当于用户线程运行的容器,当进程的一个内核线程获得CPU的使用权时,它就加载并运行一个用户线程。一个进程可以拥有M个内核线程和N个用户线程,根据内核线程和用户线程数量的不同,线程的实现方式可以分为以下三种:

  • 完全在用户空间实现,对这种实现方式而言,M=1,即N个用户线程对应1个内核线程,该内核线程相当于进程本身。
    • 优点:创建和调度线程都无须内核干预,因此速度相当快,并且它不占用额外的内核资源,即使一个进程创建了很多线程,也不会对系统性能造成明显的影响。
    • 缺点:对于多处理器系统,一个进程的多个线程无法运行在不同的CPU上,因为内核是根据最小调度单位来分配CPU的,并且线程的优先级只对同一个进程中的线程有效,比较不同进程中的线程优先级没有意义。
  • 完全由内核调度,该模式下将创建、调度线程的任务都交给了内核,这种方式下,M:N=1:1,即1个用户空间线程被映射为1个内核线程。并且其优缺点与上面完全在用户空间实现相反。
  • 双层调度,是前两种实现模式的混合体,内核调度M个内核线程,线程库调度N个用户线程。其优点在于不但不会消耗过多的内核资源,而且线程切换的速度也比较快,同时它可以充分利用多处理器的优势。

一、创建线程与结束线程

1.1、pthread_create

  创建一个线程的函数为:

#include 
/*pthread_t的类型描述,可见pthread_t为一个整数类型*/
typedef unsigned long int pthread_t;

int pthread_create(pthread_t* thread, const pthread_attr_t* attr, 
						void* (*start_routine)(void*), void* arg);
  • thread是新线程的标识符
  • attr用于设置新线程的属性,传递NULL表示使用默认线程属性
  • start_routine指定新线程将运行的函数
  • arg则是运行函数的参数

  pthread_create成功时返回0,失败返回错误码

1.2、pthread_exit

  退出线程的函数,具体为:

#include 
void pthread_exit(void* retval);

  pthread_exit函数通过retval参数向线程的回收这传递其退出信号,他执行完后不会返回到调用者,而且永远不会失败。

1.3、pthread_join

  一个进程中的所有线程都可以调用pthread_join函数来回收其他线程(在目标线程可回收的前提下),这类似于回收进程的wait和waitpid。其定义如下:

#include 
int pthread_join(pthread_t thread, void** retval);
  • thread是目标线程的标识符
  • retval是目标线程返回的退出信息

  该函数会一直阻塞,直到回收的线程结束为止。成功时返回0,失败时返回错误码。

1.4、pthread_cancel

  取消线程(异常终止一个线程),函数如下:

#include 
int pthread_cancel(pthread_t thread);

  thread属性是目标线程的标识符。成功时返回0,失败返回错误码

二、线程属性

  pthread_attr_t结构体定义了一套完整的线程属性。

#include 
#define __SIZEOF_PTHREAD_ATTR_T 36
typedef union{
	char __size[__SIZEOF_PTHREAD_ATTR_T];
	long int __align;
}pthread_attr_t;

  各种线程属性全部包含在了一个字符数组中,线程库定义了一系列函数来操作pthread_attr_t类型的变量,如下所示:

#include 
/*初始化线程属性对象*/
int pthread_attr_init(pthread_attr_t* attr);
/*销毁线程属性对象,被销毁的线程属性对象只有再次初始化之后才能继续使用*/
int pthread_attr_destory(pthread_attr_t* attr);
/*还有一些函数用以获取或者设置线程属性对象的某个属性
具体在P273,
P274还有各个属性的含义,此处不再赘述。
*/

《Linux高性能服务器编程》学习笔记

你可能感兴趣的:(网络编程,linux)