【计算机网络】TCP通信服务端的多线程实现

本文介绍了计算机网络中TCP通信服务端的多线程实现。内容涵盖线程概念、POSIX线程标准、线程函数、线程传参、线程结束、线程取消操作、线程分离以及线程同步技术,如互斥量和条件变量。最后讨论了死锁问题及其预防策略,并给出了TCP服务器通信线程版的代码实现。
摘要由CSDN通过智能技术生成

线程介绍:
线程就是进程中负责执行的部分,是进程内部的控制序列,它是轻量级的,没有自己独立的代码段(txt)、数据段(静态数据bss、全局数据段data)、堆区(heap)、环境变量、命令行参数、文件描述符、信号处理函数、当前工作目录。

线程拥有独立的栈内存,也就是它自己独立的局部变量。
一个进程中至少有一个线程,我们把它叫作主线程,也可以再创建多个线程。

注意:进程是个资源单位,而线程是个执行单例,线程是进程的一部分,进程中正是有了线程才能动起来。

POSIX线程:
1、早期各计算机厂商自己提供私有的线程库,接口实现的差异非常大,不得于开发、和移植。
2、世界标准化组织于1995年,制定了统一的线程接口标准,遵循该标准的线程被统称为POSIX线程,简称pthread。
1、pthread包含一个头文件pthread.h和一个共享库libpthread.so。

线程函数:

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                      void *(*start_routine) (void *), void *arg);
    功能:创建一个线程
    thread:输出型参数,用于返回新创建线程的线程ID
    attr: 线程属性,一般写NULL即可。
    start_routine:线程的入口函数,相当于主线程的main函数
    arg:传递给线程入口函数的参数
    功能:成功返回0,失败返回-1。

注意:从表面来看当主线程结束后,子线程会跟着一起结束,但实事情况并不是这样,子线程之所以结束是因为主线程执行了main函数中隐藏的return语句,导致整个进程退出,所以子线程才结束,如果主线程调用pthread_exit自杀,这样就没线程执行隐藏的return语句了,进程就不会结束,子线程也不会结束。

    int pthread_join(pthread_t thread, void **retval);
    功能:等待指定的线程结束,回收其资源,获取返回值。
    thread:等待线程的ID
    retval:用于存储存储线程的返回值

    pthread_t pthread_self(void);
    功能:获取当前线程的ID

    int pthread_equal(pthread_t t1, pthread_t t2); 子
    功能:判断两个线程ID是否相同
    返回值:相同返回真,不同返回假

    void pthread_exit(void *retval); 
    功能:结束当前线程
    retval:返回给pthread_join函数,作为线程结束时的返回值

    int pthread_cancel(pthread_t thread);
    功能:让指定的线程结束

    int pthread_setcancelstate(int state, int *oldstate); 子
    功能:设置当前线程是否能被取消
    state:
        PTHREAD_CANCEL_ENABLE 允许取消
        PTHREAD_CANCEL_DISABLE 禁止取消
    oldstate:
        获取线程旧的取消状态

    int pthread_setcanceltype(int type, int *oldtype);
    功能:设置线程的取消类型
    type:
       PTHREAD_CANCEL_DEFERRED 在合适的时间取消
        PTHREAD_CANCEL_ASYNCHRONOUS 立即取消
    oldtype:
        获取线程旧的取消类型

    int pthread_detach(pthread_t thread);
    功能:与指定的子线程分离,让它自己回收资源
    thread:子线程的线程ID

主线程与子线程传参:
1、创建线程时传参
把传子线程的数据的内存首地址写在pthrread_create函数的最后一个参数。
是否要进行传与数据存在那块内存无关,与数据的作用域有关。

2、线程的返回值
返回一个地址,该地址指向一块内存,里面存储着要返回给主线程的数据。
但该内存不可以是线程的栈内存,因为线程一但结束它的栈内存会被释放。

线程的结束:
1、从线程入口函数return
2、调用pthread_exit
注意:如果线程调用exit函数,将结束整个进程。

线程的取消操作:
一个线程让另一个线程结束,但也看接收着是否同取消。

线程分离:
主线程创建子线程后,它可以等待子线程结束(回收资源)。
当主线程与子线程分离后,子线程可以自己回收资源。

线程结构体:

// 销毁线程属性结构体          // 初始化线程属性结构体
pthread_attr_destroy          pthread_attr_init

// 获取线程栈内存警戒区大小     // 设置线程栈内存警戒区大小
pthread_attr_getguardsize     pthread_attr_setguardsize
// 获取线程的调度策略的来源     // 设置线程的调度策略的来源
pthread_attr_getinheritsched  pthread_attr_setinheritsched
    PTHREAD_INHERIT_SCHED 默认继承创建者的高度策略
    PTHREAD_EXPLICIT_SCHED 根据参数决定(schedpolicy、schedparam才有意义)

// 获取线程的调度策略          // 设置线程的调度策略
pthread_attr_getschedpolicy   pthread_attr_setschedpolicy
    SCHED_FIFO,  先进先出策略
    SCHED_RR     轮转策略
    SCHED_OTHER  普通策略(默认,优先级,schedparam才有意义)

// 获取线程的优先级            // 获取线程的优先级
pthread_attr_getschedparam    pthread_attr_setschedparam

// 获取线程的竞争范围          // 设置线程的竞争范围 
pthread_attr_getscope         pthread_attr_setscope
    PTHREAD_SCOPE_SYSTEM:在系统内存竞争
    PTHREAD_SCOPE_PROCESS:进程内竞争,但Linux系统不支持该选项

// 获取栈内存的起始地址和大小   // 设置栈内存的起始地址和大小
pthread_attr_getstack         pthread_attr_setstack
// 获取栈内存的起始地址        // 设置栈内存的起始地址
pthread_attr_getstackaddr     pthread_attr_setstackaddr
// 获取栈内存的大小            // 设置栈内存的大小
pthread_attr_getstacksize     pthread_attr_setstacksize

线程同步:
当多个线程同时访问一个资源时,如果不进行协调可能会产生数据混乱、操作失效等现在,我们需要使用一些特殊的技术保障线程之间协同工作࿰

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值