Linux多线程开发
2024-06-18 14:47:05 4 举报
AI智能生成
Linux后端
作者其他创作
大纲/内容
线程
简介
线程(thread)是允许应用程序并发执行多个任务的一种机制
一个进程可以包含多个线程。同一个程序中的所有线程均会独立执行相同程序,且共<br>享同一份全局内存区域,其中包括初始化数据段、未初始化数据段,以及堆内存段
传统意义上的 UNIX 进程只是多线程程序的一个特例,该进程只包含一个线程
线程是轻量级的进程(LWP:Light Weight Process),在 Linux 环境下线程的本质仍是进程
查看指定进程的 LWP 号:ps –Lf pid
线程和进程区别
进程是 CPU 分配资源的最小单位,线程是操作系统调度执行的最小单位。
进程间的信息难以共享。由于除去只读代码段外,父子进程并未共享内存,因此必须采用<br>一些进程间通信方式,在进程间进行信息交换
调用 fork() 来创建进程的代价相对较高,即便利用写时复制技术,仍然需要复制诸如<br>内存页表和文件描述符表之类的多种进程属性,这意味着 fork() 调用在时间上的开销<br>依然不菲
线程之间能够方便、快速地共享信息。只需将数据复制到共享(全局或堆)变量中即可
创建线程比创建进程通常要快 10 倍甚至更多。线程间是共享虚拟地址空间的,无需采<br>用写时复制来复制内存,也无需复制页表
线程和进程的虚拟地址空间
进程的栈空间、text段被分为一小块一小块交给各个线程
共享库、堆空间等各个线程共享
线程之间共享和非共享资源
共享资源
进程 ID 和父进程 ID
进程组 ID 和会话 ID
用户 ID 和 用户组 ID
文件描述符表
信号处置
文件系统的相关信息
文件权限掩码
当前工作目录
虚拟地址空间(除了栈和text段)
非共享资源
线程 ID
信号掩码
线程特有数据
error 变量
实时调度策略和优先级
栈,本地变量和函数的调用链接信息
线程操作
函数
创建管理线程
pthread_create()
函数原型
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, <br>void *(*start_routine) (void *), void *arg);
功能
创建一个线程
参数
thread
一个指向pthread_t类型的指针,用于存储新创建线程的 ID
attr
一个指向pthread_attr_t类型的指针,用于设置线程属性
如果设置为NULL,则使用默认属性
start_routine
线程开始执行的函数指针
arg
传递给start_routine的参数
返回值
成功时返回0
失败时返回错误号
pthread_self()
函数原型
pthread_t pthread_self(void)
功能
返回调用线程的线程ID
返回值
调用线程的pthread_t类型的线程 ID
pthread_equal(t1, t2)
函数原型
int pthread_equal(pthread_t t1, pthread_t t2
参数
t1和t2,要比较的两个线程ID
返回值
相等返回非0值
否则返回0
pthread_exit()
函数原型
void pthread_exit(void *retval)
参数
retval,一个指针,指向线程的返回值
注意
该函数不会返回
pthread_join()
函数原型
int pthread_join(pthread_t thread, void **retval);
参数
thread:要等待的线程的线程 ID
retval:一个指向指针的指针,用于存储线程的返回值
返回值
成功时返回0
失败时返回错误号
pthread_detach()
函数原型
int pthread_detach(pthread_t thread);
功能
分离线程,使其在终止时自动释放所有资源
参数
thread:要分离的线程的线程 ID
返回值
成功时返回0
失败时返回错误号
pthread_cancel()
函数原型
int pthread_cancel(pthread_t thread);
功能
发送取消请求给指定的线程
参数
thread:要取消的线程的线程 ID
返回值
成功时返回0
失败时返回错误号
设置线程属性
初始化和销毁
pthread_attr_init(pthread_attr_t *attr)
初始化线程属性对象,为其设置默认值
pthread_attr_destroy(pthread_attr_t *attr)
销毁线程属性对象,释放任何与之相关的资源
堆栈大小
pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
设置线程堆栈大小
pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
获取线程堆栈大小
调度策略和优先级
pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
设置线程的调度策略(如 SCHED_FIFO, SCHED_RR 或 SCHED_OTHER)
pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
获取线程的调度策略
pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)
设置线程的调度参数,通常用于设置线程的优先级
pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param)
获取线程的调度参数
分离状态
pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
设置线程的分离状态
例如
PTHREAD_CREATE_DETACHED(创建后立即分离)
PTHREAD_CREATE_JOINABLE(可以被其他线程 join)
pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
获取线程的分离状态
继承调度属性
pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
设置线程是否应从创建它的线程继承调度属性
pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
获取线程的继承调度属性设置
类型
pthread_t
用于表示线程标识符的数据类型
特性
不透明性
程序员通常不需要(也不应该)知道其内部结构或如何工作
唯一性
每个线程都有一个与之关联的唯一的 pthread_t 值
比较
不能用==来比较两个线程,要用pthread_equal()函数进行比较
初始化
当使用 pthread_create() 函数创建一个新线程时,新线程的 pthread_t 值会被存储在传递给该函数的 pthread_t 变量中
用途
主要用于线程管理和操作
例如
等待线程完成(pthread_join())
取消线程(pthread_cancel())
查询线程属性
pthread_attr_t
不透明,但是提供了许多操作
线程同步
线程的优势
线程的主要优势在于,能够通过全局变量来共享信息
必须确保多个线程不会同时修改同一变量,或者某一线程不会读取正在由其他线程<br>修改的变量
临界区
问某一共享资源的代码片段,并且这段代码的执行应为原子操作
同时访问同一共享资源的其他线程不应终端该片段的执行
线程同步
即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进<br>行操作
该线程完成操作,其他线程才能对该内存地址进行操作,而其他线程则处<br>于等待状态
互斥量
简介
为避免线程更新共享变量时出现问题,可以使用互斥量(mutex 是 mutual exclusion<br>的缩写)来确保同时仅有一个线程可以访问某项共享资源.
状态
互斥量有两种状态:已锁定(locked)和未锁定(unlocked)
任何时候,至多只有一个线程可以锁定该互斥量
试图对已经锁定的某一互斥量再次加锁,将可能阻塞线程或者报<br>错失败,具体取决于加锁时使用的方法
所有者
一旦线程锁定互斥量,随即成为该互斥量的所有者,只有所有者才能给互斥量解锁
一般情况下,对每一共享资源(可能由多个相关变量组成)会使用不同的互斥量
每一线程在访问同一资源时将采用如下协议
针对共享资源锁定互斥量
访问共享资源
对互斥量解锁
阻塞
如果多个线程试图执行这一块代码(一个临界区),事实上只有一个线程能够持有该互斥<br>量(其他线程将遭到阻塞),即同时只有一个线程能够进入这段代码区域
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAcgAAAFFCAYAAABoj33sAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAHGpSURBVHhe7d0FWBTr28fxL9Iqdnd3d2AHmNiNncc4dmB3d3dgY3d3YCtiYjeiiIDUssw7C6OiLorn1XP+53B/ruu53Hl2ZthdYX5zPxNroqgQQgghxBdiaf8KIYQQIhIJSCGEEMIICUghhBDCCAlIIYQQwggJSCGEEMIICUghhBDCCAlIIYQQwoh/9XWQ3hcO4JbElvIZY2s9Kt0ddizah0/uOjQtnx5zrTtqATw9u4tTQSVpUMCUF4FmxLU01Z6LoA/2Rx87PSkTaB1CiH+c/P2L3+3fG5C6u8yrX4Z5SaazZX4zsllq/YGujKjYGu8h2yl9eCSXig3EqUk+Pv1u659xYMEijj39gK/nE25fvcpjk7TkKd6IvhUu07T/FXLmSIyJNjsovLl1h6Kz3JnvEFfrE0L8o+TvX/wN/rVDrD7HF7P0RUumT1H/OAgkUK89Ecsa6ziJSZQoHVVbVCNoXkNq9XTBQ6c9b5qU1EnjYJ0kC0XSh/LGdjpXLh9h6/zO5I9rTZJK/dm0bx/7PrVN9K2YiNjWMhotxP8K+fsXf4d/5/96sBvLpx2j5NA+VEyk4+6yZhSrNZYjr9W/klhmmJrFwiRWLBIWcmTW9nX0rZSZ5J/GWizJ3WgAQ/t2oUHBFFh83lVU62mtfYfu1U1OnzjB8ePHOX7iJG7PgrVnhBB/i3/w75+AJ1w5dZxjx45FNHU7cMr1Bi8CtOfFf8q/MCB13Fs9jg0p+9G/Zgrw3MPMufex7dCScskMxw7MMY8VhPejc+zbtILZCzZxcN0IxmzxjlgcPbqPe5ORqZ2hQcG8PT6LlvXrU/9Ta8mcU+8JCg5TZ9Lz1v0gmzduZOPaCbSvWY0mI/fwNmINQojf7p/8+1dne36RPesn07nJQBZtdMFF3RasWTiE+rY1GXfMK3we8d/x7zsG6bmRtkXacipzFQqktMbk1SXu5p3KjsYeDBixBY+Xr3j66AU2RWpSNn9mMmfKSLqUyclYpDKlM8VW9wCPMNj+Tw6EJcLS5w5X/VJROL0l79/lpNemoZRQ9z5jW0Teb1DQB6u7hwmzkiHx54P3Xps60PJaJcpc3UnqhatolerLA/tCiN/gf+Hv39+FNnVu8MfuERTVjn0GXp9Kvb4hjN81iAI/PjNI/Ev8C0/S8ebaIVfe2aQmwYtVdBobxvDdU7ALOcvOy2FkK5Gb6wNKc7TuRRZ896D6O7Z3KUrHlz05urYbufQPuHz9DVibGxllUdAFmpKiYH7SWauT+qcsd+yG95D11Dnekv6h41jfPWs0zpgTQvz//A/8/RsJSPx20KX2SRrtmUwFwzziP+Hfexar3znGNxyEb18XxldOrHUaBHCwTykW5drHqrqB3HJz46b7dS5e9KXYsLE0y6TFmGFPtGhjNgSnIXvF/sxxSsauyXvxtDQnlvoH8fbKTtwTVqNcBnV+RU9ISAYaTh1GzaSguzOTxsNjM31NB9K8Xk3r9k/os8WJAh//WIQQv9c/+PcfHpDVXam/oCNZTRVCvO9ydNk8Tucfz4puBZF8/O/4dwak/hX7BzdjWtzRuAwpTTx9AH4PLrH3tDtPnzzg6r5VbH0QlzQpUpEpR1YypMtM7lx5KF6tJkWSG4ZJdNyYURfHNa/QF+/F+ERL6X2+Oqu29KVY+CVVARwdUJb52Xayrl1Kvhw8Debi6HrMy7acZY2TqdPqnmjnJrg238b4MvKnIcRv94/+/avUgGyVawSviubERi03w3S+vHgVi8KthjC0ky0pvllA/Fv9+07S0d1m/Z91aT77FSa3ZuNYuTg5szVn+W03Tpy4T1CifDjUKk2qauM5e/Uk24cV4cX2/TxPWZyC4X8chhHSbcxcbUHrtkWwjBWfsoMXMq1zcRI+v82Dx095+tQT3yA9ug9vePH0KU8eeXDn8TvCzyQPOM369Wc5NdWBkiVLqq06445dYsPaI/iEr10I8dv803//mljZGjJm7SY2bdrElu0HcD2xiJoPRvDHwltq/Ir/in9fBanuPe6bMZXT+oxky5qVzFmykj1LBhJHKt50N6dSq/VbnPY35GrLRrjkmcOGUXakMoyuBHuwpnM9Zqacw85i66l1pAZHZtUkru4+zn16sempOWaxFN7fPs69eLYUTmWGEqbD2nYAS/qUJnBbZ5qeb8G2cbafh1KCLzO23mwyL1tOk+RanxDi1/uH//7Df4yxY5Aq3fXx2I9Pw+a1jp9vTCD+3QwB+a8X+k65f+uB8l6bVALOKMNK5FOq1Syk5G+1SrkdpPWrgm6uVXo37a9sehqq+G3rrBTtvlPx05777INypH9hpeGSF0qo1hMu9Lmysll1ZdzVSCsMF6LcmVlXabTw4ZfzCyF+v7/r7/8jv41K60rDlfORNwOhr5QjTuWVKuMvK19vHcS/17/zRgEqnc9jrhzewKxBraiaJzMlR58mSHtO769gEechex9VYPJ0R7Kre3mBjx/wJBAsczZl6tqJ1E/zswcKvNkztD69115Q90Cr0maRe8RQis6DVep0qyVn2TSwIQO2vfpiKEYI8ev9/X//EXQ3ltCm2hC2HF5Au3IlKFEiohUvWpOJH9oxvUdB5Fy9/45/3RCr7sZSOnecyLbzr0hQwp4adpWoWKEy5UtkJsGHexzdvIzZMzbhU74FOS4487j2Upb3K8KtIWXpYzKVE+PK8fHWxv7bu1DxcA2OTE7Njqk7eWTy8RRvhZdHF3I6WRsa5NZ+3cOCCUpSgW6dymE4kU0I8feTv3/xd/r3HYPU3WXn8rNY2takQq7E2rWHPpye3IZ2Ew4TUsiRngP60aFyBrixij+a9OZM0oLEvvmeGi5HGFPm87VRfhvbUORgTS7OK8CVbZd4Y26J6bcXQUUI0xEcOzv2dnmJp3UJIf5m8vcv/kb/3usgv6J/epr9D1JQplxmbLQ+A92LU6x3PsizdA50aVroi4PngfdOceBVSuxtM8uwiBD/YvL3L36H/0xACiGEEL/Sv/YkHSGEEOJ3koAUQgghjJCAFEIIIYyQgBRCCCGMkIAUQgghjJCAFEIIIYyQgBRCCCGMkIAUQgghjJCAFEIIIYyQgBRCCCGMkIAUQgghjJCAFEIIIYyQgBRCCCGMkIAUQgghjPjpgPS/78btd9rEF3Tc37eA2RvP46XXun7Ae28fKlXvz5qrRlf4DwjG694Vbr7QadNCCCFiqp/7Pkj9E1Y5lmVe2oVsH2dHcjxxPfyA9JVKktI0mEtqXy/9JA4OLYZlwHX2HwqhYI3CJDPVlv9agAe7Zwyg7+xnVJq5humNsmrfEG5EwFGm997AQ0srYkX1rd+RhIUEkbr2KAbYJ9N6fDizaj4nXltgaRoLRR9CUIA/vj7evPF6zavnT3hw9xZ3nn8gabUp7NnYi0Kfv3xcfe+PWdf3D1Z7mPDdH6+3ofzgZfS1tdY6hBBC/Bv9VED6nRpG9f6hjN4zjvIJ1CzwPMzo5t1xrbiANU7FeTK+OgPMZrC7XxZuz25Mw+35mLFsJPbpTNV59zF93H48rS35Mi/D8Lm6mysJ7amQPlI8KnpCklagb6/qpDIsoLvN4S3X8bOyiAiokAvM7nIR24VdKGhm6PiSISBj56yOXZ6P3y/uy4aW2Zlh2hWHHJaYWVhgZWWFdew42NjEJ37CRCRJlpLU6VITX/eeoDjJSPjF14y/ZrFDGc43XkvXXFEmPnv6tcFr4FWmV5KAFEKIf7PoB6TfOSbUrcak53kpnjFOeEiFKXnpNKsi59r041nHdfR83gMns2ksybeeFn0e03bLSlpn00Lv7QqalNpLkfHNyBpVvkSi91jHoLOVObaxvVqdap2RBJ8bhm1fKxYfcqLAF0EWFT82tS3EbvvLLG/0MTR/hhdLHLIzP3YzSieNamRax93dh8i52I3pFaMbkHpe3z7P7ddhJMleglzJI73ZgMdcufQIP5OEZCqcjzSSuUII8beJXkD632BNL0fGhvZh6yR7koTng1rhfQjFKnUqzK9uYVdwCbIdd2Sg2VQWFj7LvuCadKyW9nO16LWcJhWv0ebcDOxia33fEXCwDyUX5GDvxg4RFeQX9LxY3ICS51tzY7EDkUdCo/b/DchXLKxVmB0FhuKQNqqADOLigllYTXJjVuVovMlw7zg1twPte2zGqvdhTk2u+On9vFrbmtojj/EijSPzlo6gdoZo7FkIIYT4JaIZkA84tP44JjVbUinFlxvpgOOTaDvlFAFqSRn4yBW3WAUons5KLS/DyNNhFeMcEoXPp/fcz8ypTyg1oi0lYv9gQ6/T4X9+Pr33pmHoyHqk/Wb2APZ1y0Hd/ekplzmO1megoAuyodoEZ/qW+LrcMgRkfpyzzqN7USNjspEpeoICIE2pyhQwvc+Fu+8xMf3AraMHuONn+oNjkJCieC2KpwojxCo9xfOm/GpI2Qi/NTjWPIR5XBOqLl1GkxRqn/4xSxz741c4FnvDhrC7X+6oj88KIYT45X5iiHUrPStP4EKoD88CE5A+cSyUEoPZbnecirNTs2KGA/G1WSGEUyNrcbj6JVZ8Ua0F4za9Mc1WPie2hRYzQa958NaaDKlttFNq9QQEFmfUmXnUi6rQ07kzqWorvPqvp0v2SPETtJ8+RTdT7tp+emb5Opb8cGmTg9Fva1IqVaSIU15zYfMtktUpR/pIuamQgir9BuMQtJr+44/ibfrdWPyWGrLmhTozu6ctPxwZNQSkwwOaN7zJEt1w1vXIAXdm0WxsPMZVOUjXV04SkEII8Tf7qZN0DPzWOVLKtTnnZtpjGEQMONwP2wU52LO2MjfW7uNdDgfqFo/Lrs5F2Vbx/A+HMwP296T4gpzs2dTJSKUYhbfraFZgJzWvraVZRIEaTn9vBvYlrtDp0UoafDPu6sv6lkU4Uvcyi+pGetJ/Lz2Kr6TQkfW0Tq71GRN8leVDF3E5yOz7FWSYDouC7RnbrjDROjRqEB6Qj+i9Lg+L2l2khcsQ4s5swuxMC5kW3IsGEpBCCPG3++nrIKMU+gbXJVM5+jr294cUgy+zbGB/5h55ZhiN/EsCb1zFPXVOskceXVWFvPTkddrURk/qQf8e3w/WxI1jeMs67mwYy4iFe3D3DYt4/kfCAvA44EaCmo60bNkyvDlWi8P5gyGUbB4xbWh1ktxi721/ornWLyWoimPhKzjvPsmW02lwsE/2/TAWQgjx20QzIP3Z1c+WEmXKUWPcQe5tGYR9ubKUKNKUJc8/RoEJJmZJSJLkB3XO+xscWnMPi8yfj83p3NYxoF1rWrf+2FrSwsmFx0YTVMfD8+e4EfaCM8sXsGDB57Z8qyuPU6YlrYU2a2Qhz3nhmYRkSQ0/NQidpSU+h0dTu0QXNr98w/NHXt8PbMPFl/pb7Jg2ljFjxoS3sTN34X77CIvHRUwb2tTt7uhN/mqsWVO0mT2vR3fnRI66VIindQshhPjbRTMg41Jz8ilcTx5nt1MVstQbz77jJ3C9uI62qbRVKO/x8bHA0vL7q/S7eJ6ruWyxjXRqqmmm8rTs0JGOHbXWoQPtaucnodFSNJgPKe0YXT8jgb6++H5q73ly7yGWqVORyNhyvh7cfZWGDOkNA5825KnTlxkbz3L14HDKxb3F0uYlKNVsMMtOPCIgYokvhelRYmWhSruudOvWLbx1bVOZHFlK0/SPiGlD61A1G7F+btT6C+bZm9K3X3d6tS0TzbNzhRBC/A7RDEgjdE9wu/4KJTSEIF0IgQ+v4vY+C9kzGQJIITjIj6Dgr27Zpvdk35Yd3Hp4h1uen+u1WHFTkrtEKUqV0lrpMlQokQ3jBVRcijYfhNOA/vTvH7l1p1JGC9IZLjvR5ozsnetpLmfOT96vDonGU+dPYlOGoYf3MabMB1w62lKynhMbrvtrc2jMElKwcVXi3jjNqVOnwtvpi/d48+4xV89ETBvaVcvyNC2U8P/xwSamVIs/qJ1TjjgKIcQ/6S9txxX/2yzrWJ/2zu4oBdqzyKkA52av4EXtBhS/Po5mrRaSYNBZZtb5fF6rgffxGUy7XIv5XX0Z03ogG919/tqxOqM+8PzZc1KmTvPtyTH6p+x2OUDScmXJEkXumFhlpUqXGew6vYtBBawIs4y8lmDcXFy46BtKcHBwpKZDHxZKSOQ+nYLf5WOc8NIW/SFv9kyYye6TC2hXsQJtF7tj2K3Qv9pGPztb7Mbs5PjSqazzkPvDCiHE3+knz2L14cyIGpQZ+Qy74fOZO6g66T5cZu2I7jidLca8rVOoFf8Wawd3Ysi5QkxwnkSjbBEXOby7MI8urZeRcvIuplSPjfvqEfQbtxv/xObc8StIn/ZlSBnfhjhWVliYK+iCgwj0e49l7gY0KPSU1SPX4B5mHvUJQIofV9bOw9O2L/bpI+bSh4SQqd4oar4dSM0OD2h3bDs9cn2VkD88i1WvBl8Ir64c4oqXCWaRDi8q7/YxbOR7OkxrTLpPuxqK+nOtyVKxNJmsrbH+Jq2FEEL8G/xkQOp4uGk8y0Pr07+uJYfGD2Pysv14F+nN9GlqMGXQ0kD/igPDGtJqX0lWHZpE6afzaVFrAkq/LazqVphPo5wBz7h04hjnr9/j0TNP3rx7z3tfXz4EBoVXZzolJfUnr6Rnwecc33qO16aW/MzliGG6IOLnr07aB6tweVqAbp3KklB77hP/nfxReBWFj7nQLqXWF5nuLvOb12Phwzh8e3g1DF2IgpnF1zcPUAgNMKHChKNMqRHdO+oIIYT4X/LT10F+psfr5AZ2BhSinl0OEmi9n+gec/rsB/KXzUVcdV7PR8+wzpA+iuOK/6DAcywbc5EMf3amYpRfOyKEECKm+X8EpBBCCPHf9ddPthRCCCH+wyQghRBCCCMkIIUQQggjJCCFEEIIIyQghRBCCCMkIIUQQggjJCCFEEIIIyQghRBCCCNi3I0C9hw8SUhICCmTJ6V4kXxarxBCCPGlGBeQNRp2wc//A6WKF2DCiN5arxBCCPElGWIVQgghjJCAFEIIIYyQgBRCCCGMkIAUQgghjJCAFEL8Fv733bj9Tpv4go77+xYwe+N5vPRa1w947+1Dper9WXPV6Ar/IcF43bvCzRc6bVr818hZrEKIX0//hFWOZZmXdiHbx9mRHE9cDz8gfaWSpDQN5pLa10s/iYNDi2EZcJ39h0IoWKMwUX5neYAHu2cMoO/sZ1SauYbpjbJirj31jYCjTO+9gYeWVsQy0fq+IywkiNS1RzHAPpnWY+DDmVXzOfHaAkvTWCj6EIIC/PH18eaN12tePX/Cg7u3uPP8A0mrTWHPxl4UiqstaqB/zLq+f7Daw4TvvgS9DeUHL6OvrbXWIf6XSEAKIX45v1PDqN4/lNF7xlE+gZoDnocZ3bw7rhUXsMapOE/GV2eA2Qx298vC7dmNabg9HzOWjcQ+nak67z6mj9uPp7UlX+ZlGD5Xd3MloT0V0keKR0VPSNIK9O1VnVSGBXS3ObzlOn5WFhHhFHKB2V0uYruwCwXNDB1fMgRk7JzVsctjo/UY+LKhZXZmmHbFIYclZhYWWFlZYR07DjY28YmfMBFJkqUkdbrUxNe9JyhOMhJaaouGe81ihzKcb7yWrrmiTH329GuD18CrTK8kAfm/SAJSCPFr+Z1jQt1qTHqel+IZ44SHVJiSl06zKnKuTT+edVxHz+c9cDKbxpJ862nR5zFtt6ykdTYt9N6uoEmpvRQZ34ysUWVLJHqPdQw6W5ljG9ur1anWGUnwuWHY9rVi8SEnCnwRYt/jx6a2hdhtf5nljSIHZ3R5scQhO/NjN6N00qiOZOm4u/sQORe7Mb1idAJSz+vb57n9Oowk2UuQK3mkNxvwmCuXHuFnkpBMhfORRvL2l5BjkEKIX8f/Bmt6d2FV2tmcPbGF1c7OODuvYPnCPymfyY4hM0dQM0tCbcOjoDdPR9PJE3H8GI4GYeo+u0VK8to74ODw42afPzVW6rqM7+nreet2ndc5cpMl2uH4K+jRh1mTIkse8uSJquUkXXz1MzC832jx5e7hqXSsYEuzKcfx13oNXm0bTqf2rWg23IXLntE8sCt+SCpIIcSv4/+AQ+uPY1KzJZVSfFnOBRyfRNsppwhQS8rAR664xSpA8XRWaiCGkafDKsY5JAqfT++5n5lTn1BqRFtKxP5BCanT4X9+Pr33pmHoyHqk/Wb2APZ1y0Hd/ekplzmO1megoAuyodoEZ/qWMFZuGSrI/DhnnUf3okbGZSNT9AQFQJpSlSlgep8Ld99jYvqBW0cPcMfP9AfHICFF8VoUTxVGiFV6iudN+dWw8lf81uBY8xDmcU2ounQZTVKoffrHLHHsj1/hWOwNG8LufrmjPj4rfooEpBDi1/LbSs/KE7gQ6sOzwASkTxwLpcRgttsdp+Ls1KyY4UB8bVYI4dTIWhyufokVXwxlBuM2vTHNVj4ntoUWMUGvefDWmgypbbQKVE9AYHFGnZlHvahGQXXuTKraCq/+6+mSPVL0BO2nT9HNlLu2n55ZjEWSHy5tcjD6bU1KpYoUccprLmy+RbI65UgfKTcVUlCl32AcglbTf/xRvE2/G4vfUkPWvFBnZve05bujo4aAdHhA84Y3WaIbzroeOeDOLJqNjce4Kgfp+spJAvIXkoAUQvwWfuscKeXanHMz7YmtTgcc7oftghzsWVuZG2v38S6HA3WLx2VX56Jsq3j+h8f6Avb3pPiCnOzZ1MlIpRiFt+toVmAnNa+tpVlEgRpOf28G9iWu0OnRShpEPvv0E1/WtyzCkbqXWVQ30gz+e+lRfCWFjqyndXKtz5jgqywfuojLQWbfryDDdFgUbM/YdoWJ1ghweEA+ove6PCxqd5EWLkOIO7MJszMtZFpwLxpIQP5ScgxSCPH3Cn2D65KpHH0d+/vDicGXWTawP3OPPDOMRP4lgTeu4p46J9kjj66qQl568jptaqMn9YTTv8f3gzVx4xg2kTrubBjLiIV7cPcNi3j+R8IC8DjgRoKajrRs2TK8OVaLw/mDIZRsHjFtaHWS3GLvbX+iudbPElTFsfAVnHefZMvpNDjYJ/t+EIu/RAJSCPEL+bOrny0lypSjxriD3NsyCPtyZSlRpClLnn+MARNMzJKQJMkP6pz3Nzi05h4WmT8fl9O5rWNAu9a0bv2xtaSFkwuPjSaojofnz3Ej7AVnli9gwYLPbflWVx6nTEtaC23Wr4U854VnEpIlNfzkIHSWlvgcHk3tEl3Y/PINzx95fT+0DRdg6m+xY9pYxowZE97GztyF++0jLB4XMW1oU7e7ozf5K9FmTdFm9rwe3Z0TOepSIZ7WLX4pCUghxC8Ul5qTT+F68ji7naqQpd549h0/gevFdbRNpW1ulPf4+Fhgafn9zY/fxfNczWWLbfjFjRFMM5WnZYeOdOyotQ4daFc7PwmNVoLBfEhpx+j6GQn09cX3U3vPk3sPsUydikRRVZC+Htx9lYYM6Q0DnzbkqdOXGRvPcvXgcMrFvcXS5iUo1Wwwy048IiBiiS+F6VFiZaFKu65069YtvHVtU5kcWUrT9I+IaUPrUDUbsf7iUS7z7E3p2687vdqWUT918TtIQAohfi/dE9yuv0IJDSFIF0Lgw6u4vc9C9kyG8FEIDvIjKPir27XpPdm3ZQe3Ht7hVqTLFmLFTUnuEqUoVUprpctQoUQ2jBdQcSnafBBOA/rTv3/k1p1KGS1IpwZkVDXsO9fTXM6cn7xfHRaNpy6TxKYMQw/vY0yZD7h0tKVkPSc2XI980YXKLCEFG1cl7o3TnDp1KrydvniPN+8ec/VMxLShXbUsT9NCHy97+VmJKdXiD2rnlCOOv4sEpBDit1H8b7OsY33aO7ujFGjPIqcCnJu9ghe1G1D8+jiatVpIgkFnmVnn83mtBt7HZzDtci3md/VlTOuBbHT3+fnjdFH6wPNnz0mZOo3xE2P0T9ntcoCk5cqSJYrsMbHKSpUuM9h1eheDClgRZhl5TcG4ubhw0TeU4ODgSE2HPiyUkMh9OgW/y8c44aUt+l3e7Jkwk90nF9CuYgXaLnbHsFuhf7WNfna22I3ZyfGlU1nnIfeG/VXkLFYhxG/gw5kRNSgz8hl2w+czd1B10n24zNoR3XE6W4x5W6dQK/4t1g7uxJBzhZjgPIlG2SIucHh3YR5dWi8j5eRdTKkeG/fVI+g3bjf+ic2541eQPu3LkDK+DXGsrLAwV9AFBxHo9x7L3A1oUOgpq0euwT3MPOoTgBQ/rqydh6dtX+zTR8ylDwkhU72xdLG14On2P6nZ4QHtjm2nR66vEvKHZ7Hq1eAL4dWVQ1zxMsEs0uFF5d0+ho18T4dpjUn3qTRR1J9tTZaKpclkbY210cQW/xQJSCHEb6Dj4abxLA+tT/+6lhwaP4zJy/bjXaQ306epwZRBSwL9Kw4Ma0irfSVZdWgSpZ/Op0WtCSj9trCqW2E+jXAGPOPSiWOcv36PR888efPuPe99ffkQGBRememUlNSfvJKeBZ9zfOs5Xpta8jOXIobpgoifvyFVcgRze88yXJ4WoFunsiTUnv/Efyd/FF5F4WMutEup9UWmu8v85vVY+DAO3x5iDUMXomBm8fXNAxRCA0yoMOEoU2oYLogR/yskIIUQv5ker5Mb2BlQiHp2OUig9X6ie8zpsx/IXzYXcdV5PR89wzpD+iiOK/7DAs+xbMxFMvzZmYpRfvWI+K+QgBRCCCGMkJN0hBBCCCMkIIUQQggjJCCFEEIIIyQghRBCCCNixEk6Z85fZezkheGPDSfofGQTNw7m5mYsmTOaJIm+ObdOCCFEDBYjKsgSRfKRWA3AyOFoEHE2a0EJRyGEEN+IEQEZK1YsWjVz0KY+MzU1pWWT2tqUEEII8VmMOQZZoUwxMqRLrU1FqFalDCmSJ9GmhBBCiM9iTEB+XUVK9SiE+J6NW/bRudfI8BYUFKz1ipgkRp3Faqgi06dLFf64elWpHoUQUXvh6cXN2/fDW1jYr/suEfHvEaMC0lBFtm5aR6pHIYQQPxSjAtKgQtli/NG+CcmTSfUohBAiajEuIA1VZMM6dtqUEEIIYVyMC0ghhPhX0nuyc1wfFrp6cmJqRwZvfoBee8pA73Uf99v3uH//vto8uHXfk0Cvh9zyMEx/bvdue/DMT1vIKH8uzHCk2egDPIv8A2KgGPd1V0IIER0z5juzZcfB8Mf7Ni8kdmzr8Me/n54HW4Yy17sZ45rHwf2iJ3orU0yCzzLuj8s4zLPDtfN8UkydQo2EoQSZJKdA0TTcGVGJFmfTUzTpey6vOUvulWcZ9LQ9TY6lpVgKrRbSP+TQ8TwsvrGAmuH3Rwnk3pkTPAwyJ/K3W+q9TjBtyH5yjRhNjZTasooeXdzMlC+eCe3rrv/zJCCFEMKIfy4gwc91NJUr76bGqj8xO+eGv6kJwdfXs1FXi2aJj7HgZh66VEtPrLAQwrI2YnhLS6bXGEuKlWuocrIjLQ7VYvXsbKx1GE7ixRtpnzYi/vz2dqXG3trsnmWHjaEj8BgD7cfxvkJpUphAsM9b9DaJiW2YPfglt24HkzJ3BhKYKbx13cD96tvZ1j0b5oZlYwAZYhVCiP8xNiX6MndyOazjJibk/E7OXL/KibMvsdI94OwpN8xM33HzzA52vrelX7timN3czbEE9lQJ3MSoNSkYOr4eKTx2czRONexSfawN/Ti16zoFapSKCEeV//kDXMjSiCYlClO0WD4sbh3hYbw8FCtWjEJJfHDzTUmRYoWo1KQO6ciGvX3GGBOOBhKQQgjxP8eaIl0m0jPlRfa/KUo9hwIkTlKRZk3Lkso8D3Vb16dsmoQUr1qexOi4ufsYCapmYVvfdWQcMpTKiXXc3b2bC7fX0LFmNapVU5t9FTodLkCNUh/jUQ2ATM2ZOSA7z67fxP3sOra8LUJ+HnLjxhW2bXQne7EEPHW7j7dJehwXLqZN1pgUjxKQQghhVMb0qSleJF94M1w7/fsFc+vAGtZtdGHjuk2cehTIHTX44lQrg/W1Qzwvbkf6J4c5na4mpeM+4cjlrNSokAB0N9l9LD72dqmxDHvCK+9Qte8uu44mY9L+Q+zduze8beheiPRVaxApH4mdNjd5kvpz98xJTh+/imfAMy6eOcOZ08c5/zAQz6vHeJHegRrZEpI8XTLiasvFFHIMUggh/hfon3Jw6Vqu+jxky2w/ep7vz9N2TdkcKweJvD3wtMlK2uB73NWnJ3sCL+4l68WxpY2xuTaOGmNSsHJ9W0xX1MXuTh9OtDpDw2GJWLyxPRGHH/3Y27UGe2vvZpZdRELqA/0JsYir1qo6dGGvcG7dA7+hG/kzhzm+u3vQ+HQDtowrTqxgS2KFBapFrXWMGl41+ImADOTpo7cky5Dm2zOYAm/gPMYFq1YDaJgt6gPZ+qd7GT/9DuUH9cQ2qdb5j/Dj8uJRrA6yp0f7SmSIxrF3w9nOX+9D6m6tYODUR5To05+GOWNrvcboePnEkwTp0qi/jEIIEbXAk/2xW1aMbctr8WD5KFzuKpiaaE+GU4iVuRb925UinrptuTauOmOSL2d9uzS8XVoPh8f9WBBnAI636tOrfHzCFw17yvalXnTeN4uIfPTn6Pi2TDkTjFksCHh4ijMBuSifKxFmJgpe13ZyO14VymRUt1iKjuB0TZk305FMf0ch/T8k+kOsXoeYWLMqbead553W9YlFYtLEPkvvWu1Y4uavdX7L1CYJCR5OwK7eSI55qaHz8hTrFi1h6dKl37TF82az4dw3P0njzZpWmag66YIa2xrdXWbYp6D2vNvqr8yPxCZtoQJYHexK2YqdmHvy2XeXCTw7imrFmzBszQVef7wuSP+MnTOncDReMWwzmBAYGBip+ePj9Y4AbVa8DjChWnEqdV3GBW91fadHUj5zFrLnyEGOKFr2zOko2Gff53UIIWKAQC7uOkfmmpVIFHyVbas8SFujLnXrfmwOFAs8yrXQ1MQxzG4YXj0an4rFQ/A468yIFQHUrx2H/YcVbAuaEfDhAx/U9v7iHm4Vjjy8GpcKgzaye81EOpROSrziw9h7bDnVTbzI3m0x2xb2I3NwbMr0XcCWHXvYNyfmhaPBTw2x+t9cS98Wg7htN5flo2qS8Yt625sz09vS+XQNtqzrQJaoanG/q8xpWgPn4ts52vwp02ed5J1hF+YLeh7vnYGurzfb2iTU+iLzY2PLnOyocYvVjT/+j79kYe3y3Oh2hVlVI1dzep7tm8O8k28w+3I3TN0z8uf2jlVcz9iCBvniRexpGbpDgwnNXI9h7YprFZ837tuXMnn0NM6kdWLtmlbEWt6GppMfkDJDHLxunuZN0tLkSmqmzhvI8yuXsW6/i2NT7UgUvrz6e/ziJPMHdGGse1mmj0rGnPEmzDo6nCLh5XgwrsNKYX+iHru3Dqa0+pZ1fq/xCoxNqmQxbdRfiBgs8BQD7JdRbNsyat4fQaWmx0maL9HnSkbx4doRawZc306HtKboro2j+pik9C20hf6HU9PGaQRdkq/FYWhCFrl0IJ02vLqvW0321NoVMbyqf8vtE0c4cmQfB695k6REC9rVzEps3wMMH+FNhylNSKNux56dW8OUifsws2tDMzWc61XNoVasMctPH4PUPdrNxEWvqNUhLy/c1DLQInK46QkNNcXMkBMqJSSAkCSFqVE6A+Z++xndfitJ+06mQ1Yd7+MkIlGUA9p+ajBmYVUFD7a0NPZfogZkq/zsre3G8vofA0QNSIfK3Ol5kWkVvhzI9L68iwP3Q7Ayj17BrOgCCUhQiEZVsn855v7OjV3n9GR+O4t6o4Pps3EJbVLsoVPRprjW2syBmTUwO9APuz/fMeDwEppo1x59ovfEdbcb8VO40r5nGDM/BqTvfnqWGIjF7KNMqhR+9a4QIsYJ5PH2XtRfZ8ve9Q2571SUtg/q06qglfa8Kuga68/bsm3HH6Q3jRheHZ18ORvapdEOAem4MakWQxMuwqVDuog+v310q7mHWru04VX9IzZPWMDzXI1pkPMBS+ef4A0Kvm67uBi/OhXTm6KEhZGu5jC65rjBivl7Mak7gM7FP+7uxxx/+SSdYLcVDJntSnBsS0yC77B73RuKtCpN8khFmhL8AfJ3YGIXtRLz20zLDKup4LGVNj/8nI0EpP9tTh5/SEB4tanj4oz2nCmzhB6FP0aYP0dH9+ZJ4/m0yqb+WoTpME9dnHL5kmq/OHqe7p/PkvN+xP4i1D8LU4PRpmh7uth9/GX7mp5XZ13xLpCP5AGmJE4czIlhdej9uiZVH6zlUaNlOKU9z8mgCrR3+HgxrR9PHgeQOn3yT+sMvjSGit31TF+WijmOi7gT8pLzbpCvRFoMta8+OIgUTRfi0q9YjLljhRAxl54XJxYwarwLr9LkJ+mz09xIZEedEpnImjUtcSJtrpRgH96FJSVNfBvSFjFnTZ1RJF+xkXZpTHm9azT9XO7x7OhOfEvWo0C8iI2x4nOZTecT4NCsHYNGNSOHYcP09UkV+icsdezJh+Eb6JE9ysolxolWQOpfuXHS3ZtYFiaEBgUSJ1slimf4/CHqH8ymdsMXDDw1njJRnYXit4VWWdZS2WMTjvECuX/2JI+CzCMdBFUINU1K/tJ5SWb6bUDqPXcyYdB2nloYylOFp0eXcD9re8qn+ZjIIXjsWcfboi0pkVTtUwMycaWBjGicVQsqPU8WNKDaiZIMrJHayMHXMJ7vnsDZsnvZ1Fnb84os8CEH5g1l0Apzeu1cQou0bzg190+6b83M5PWjKBewk/6OI3hebyYzupcjlfbx6F+sp63tUPw6zWdm78qkVfuDL46m4p8mzFydmJGVL9PiwFBKfvo49dye15gx8RZx0KmABKQQMcDrvXPZbNOILuFnL/pxZ89yFq3Zx8WH79Qtm4m6odajU3ecg0LCMDG3JFWtsSyveZaGo5LivL0rGdUNls/jmzwPtsTK2N59WDAfSEzurOqOuu4Wi7v0YquXZaQRsjBCgkMxs7T4vG3UB6PP3x3nsTUwdqArJohWQAZfXUK/aaf5YAFPjx8i45RbLHT4fGxMd3MK1buFMnXvQPJFtUX/IiB9WdsoOUPe1aO0do9Axc+NHS8bc+qUE/nMf+0QawQ9zxY1xMG9CQtaZzFSIeq5t6Iz6/Nsx6VjpApS78XlTQuYNs2Z+/n+ZOLI9hTyWseg3mPYY9aU2YuGUT29FsFPDzCxe3eW+JSlrWN96tezJ6f6m+Xrthqnjn04mGEYq+Z3pcDd4ZTtZ8kC58QMK7qSZJ2rkvbTb6XC27MruFZhJ4cH5otxp1UL8b/imvsd7j14Ev7YoXoFzD4eOxIxxreFlBGWBdoza9Vyli6ZQOP88Yht/eVioZ6evLizhSGOjWjUyNAaUq9WTfpufBZeyRtjapGGSt0X4OzsHN6WjmhALotY/M5fwdAE2cj+dg/zZs9m9jdtHnt9cqqBFqrNrTE1w//RE5J1c2F9myS4b1/O6jOvCE1ajla1UvNk71IWLFgQ3hbvvk/8uhOYUseCp17mJNCyPV6+FszZs53eeaxQd/4ICwkmxErd01OfMzG1IXHKlKT81FKQxEbqRiH+aUdPnmfmfOfwFhLy43PjxX9PtALyE7XkDtGZY2YR6UCjyvfJU/RVujBiyBCGhLeBVIl9iUcfrI1Uav8QtRIMytyUIcOcGDRokPHmNIimhT6dB61JSNkBi5nmmJ/YHluZuvsRYSYJyF++KEmVEEIj1d/K84PM3uZJ4e5zWTiwEikjv/lE+SlXuxQ5Yqsv5f17fGPHI76JurBNViq06kSnTh9bW6rnSWwo7bUFhRBC/BN+LiAJQRdihvkXZV4A7tdvkrlIOfLny0e+8JaNxFZmWFtbaPP8P/lfxGXOPObPn6+1lZy895Z7x1dE6lvHucdvuXVgWaS++aw5+SKiig28yvoxIxg+bChDh37V+rWkUvZC1B+xi2cmcaMMdbNYpthkr0Trzp3p3LkdVdjH6HWvyN3EMN2Z1nY5SWQay/iH6nOQGU0Hs/axDn+14tYlSUrcwAACHq+iQ94sZEmfUq0k05MlSy7qTXPlvb8/X9WyQggh/kY/F5BhIYSEmqsBqfBwY2/6Oj9GrwbP0RPxKVU6daRgUcIrTSurLyvNyML0Lzg8uzOOjo7hrd2ITdzShRkfklWCCXjvg6+vr9Y+kKa2E3ZJI/eFkK1JL8on8P/c5/MO3wAtZuLaM2LrVlw2bGCD1tbO6kPt3DYEKXnptv0Cp9cPwD5TdIc3dTx54kmJJo6U+uGVGXpe7nVhb4pSFE8Vyr17D0mXKT2W2buz5uYVrty9x5UpdsSpPIkr9+7zyFfh0qgSctcdIYT4B/3cZR7BVxlXtRu+LStzcdIZKi1dT5fAsZQfn5xVe/tHOkHnJUvqVca98wVmfLxo/4uTdAK4e/IwD0PiRrqMUkGnJKZAufxGz2L92tuTY2nQbA9lV+9gZLnEvN37J1UHvqXVnCl0LZPic1gHnmPhwOVcxwqzr/JaeX+NrTsDsG1WkmRf7SoooQo5mk2gS6nPMfXOuTkVrrTizLSqxPbeR8/KM0jnvJPeuSNOpQk86USF6enZ6NJJu0BXo7vDrNp2uDY/g3Pj98ywr4FHLzcWlL+Kk219LjvuYmW6uRTdYcehagdotb0kC5d3JN/37l4nhPit/snvgxT/G36ygvTDz/scE3vvIO/UpfQv+oJVM/aSt10TckcuvHS++AXEI55NVIOVsclWphZ2lSpQocLHVpGqFQ3hqM0SJT3P9o+gYYNFJB86j75qOBokrtyXKS31zKtWluazzuD1sRQ1S0H+qjWpWb061b9ulfKSMn0R7Gt8/Vw17KtWJF+KyGPJerUaDVArYx1hgR5sdBrCSdvOFDrgSJUWg5i34xpvTZKRPV0c1EL4C74nFrPocT3aOKQi9PpWttwpS8Visbi8YAQbMoxkRo+i4dc/Gv47UlTvgMPbYTTts5XHUZ3hJIQQ4vczVJDRFfpwhdI4aRql/iJ3JUDxVk6Pr6Jktp+puAVpM3z04bDSJ6+9MtMjVOtQ+W5WWiarr6x6r01/13tlQ/OESt2vZw56pOyfUF/JHCen0nqFm+KndX8Wqrw6OU2pm85GKdR9g3L369f1lRD3yUrV8uOUKz+Y75OQ14r77jlK9yo5lYKtFyuX1ZcX+s5DObZ6gtKlem4lba7qStcpm5UrniHaAqqQm8rsakkV2/FXlKCQu8qS+qmUbD12KVfWd1byp6mlzLsR8cN9N7ZS0rZYr/iqj0MfrlfaZEmmVJ/lpkRakxDibzR93iqljL1jePvwIUDrFTHJTwVkeADduaO8Cnig7B1pr6RN11BZcvNjuoQoHhuHK106dVCaVcikJCw5WjkT+XfKd5PimLjeDwIyQDk1vKySLl1iBauyyqQLn5Pr9YmZimMBG4WsjZVpJ16qryRqQR4uSvcCCZVyk64ZDZi3F7cqy1Y6K8vHN1ZyVpykuP0ghULU9Tk1qaIUTBtPSVagoeK06rzi+c0LCFAeHV+iDKybW0mUvIIy9mREfAedH6OUTF5XWfLQV3GdWEGxSVRHWXT7uXJ26VBl7JYHSojnAWVK105Kq3JplHRddikfwpdSFO/ze5UjD6Kb3EKIX00CUvy1W83pfbh7aBuX4taiaemIIU4D3d0tTHe+hVW2olSpWTX8IvlPAk8zf8hFsg/5k4rfuS1D8P3THHlsSfaCBcmUMNJ4a6AHu9ZdJpVDYwp9/pFR0r+6zyPLzGQ28rN0d5bStetGXifLTJEG3elXL+cP7ljzjjOrV3MvWSVqVMpF4u8OA/ty97gblLAlW/hK9bx+8oLY6dJi7eXG0btxKFc68+cbAOhfsH/eQq6YFaBK3doUTvHDMWYhxN9AjkGKvxaQQgjxHycBKSQghRDCiODgkE930LGxCf/2RRHDSEAKIYQQRvzcZR5CCCFEDCEBKYQQQhghASmEEEIYIQEphBBCGCEBKYQQQhghZ7EKIYQRcpmHkIAUQggj5EYBIsYNsbbqPIgGLXsxaeYyrUcIIYT4VowLyNde3mp7i897X61HCCGE+JacpCOEEEIYIQEphBBCGCEBKYQQQhghASmEEEIYIQEphBBCGCEBKYQQQhghASmEEEIYEXMDUu4fJIT4jgplivFnF8fwZmFhrvWKmCTGBaSJiYn2SAghopY/T3bq164S3szMzLReEZPIEKsQQghhhASkEEIIYYQEpBBCCGGEBKQQQghhhASkEEIIYYQEpBBCCGGEBKQQQhixfc8R+g2dEt6Cg0O0XhGTxNiAVBS5U4AQImoPHz/n3EW38KbX67VeEZPEvICU+wQIIYSIBhliFUIIIYyQgBRCCCGMkIAUQgghjJCAFEIIIYyQgBRCCCGMkIAUQgghjIgRAXnvwRN27Dka3vz9A8L7Tp+78qnvnY9veJ8QQgjxUYwIyNixrZk+dyVTZi/XeiIYptdv3oONTRytRwghIqRKnpRcOTKHt1ixZLAtJjJRYsgtZSbNWMqu/ce1qc8G9+2IXSVbbUoIIYSIEGN2i1o0qY3pV3uBaVIlp1L5ktqUEEII8VmMCchUKZJSrUoZbSpCq2YOmJmaalNCCCHEZzFqYD1yFSnVoxBCiO+JUQEZuYqU6lEIIcT3xKiANDBUkenTpZLqUQghxHfFmLNYI/P0ekvypIm1KSGEEOJbMTIghRDiR+54POTx05fhjyuWKy6HZGIgCUghhDBixnxntuw4GP543+aF4TccETFLjDsGKYQQQkSHBKQQQghhhASkEEIIYYQEpBBCCGGEBKQQQghhhASkEEIIYcTPB2TgReZ06cyMo6/Qa10/w9/jCu5vjS2p48He+UxfexbPv7LiXyKAVzddufIoUJsWQoh/TvCtJbSqM5C9z368UQx+cZtrN25z584d7ty+wbXrj/AxPKF/jEvn8jRbfIvg8Dm/pH91lyvut7h9+7babuJ+9yWBr+/hpq4roi+i3bpxk8fhKzQmgIszmtFo1AGi8VL/Ev0DZ/5sOYHDr7WOHwrm1valbLvpp01/FMy52V0ZvOXhDzPsJ6+D1PPKpSOlBvnTZUxDMpop6MMSkTDkOHsuB2D2Rdyqz5nkoPGoDpT4ePmQ+h+1onkFFmZYwLaxVUnOS04fvE/GKrakMg3m2sQa/BE4hkMjSmAd6Mae3f7kq1WKNJbqsgFHmfbnWu6aW2BqErG67wnTBZOyxggGO6Qh4vJeH04vn8MxTwss1ReqhIYQGOCP33tv3ni95uWzxzy4exsPrzCSVxzKls1OlIoXvmAE/RPW9OqI830zzL7z88NCzSjZby1DK8XWeoQQ/0b/9HWQ+hd7GVizOstNa1EunTkWGapTzWYXqy984N09L2xypCee8gaP58WZcmgMVuMqMvBxPgomfM/lDYdINfE4Gzql5trUVnRbch2dwypOT7Dlyy1TMBeHl6P5uZyUTunDxRWHybbyEsOetaX+sSyUSaNt7MIecmBXBmbfXU7dRMF4nDrAXT+zLyqssLfnmDtiFxkHjaRmqo/PhBEaNxuVy2Tl//fp6Xk4pwZ1nwzh7CTbaK3L+/gwmo0NosvcETikuM6cATtJM2QkdRJfZWT1iaRfuQ5HZQ9Dh12mwsThVEmmLRjJzwWk1z56VRvCy0rVyWYZyI3N83jssJN1dQK4/tIE00sz6eZemXkd8mLmd4wJI3UMvjCNqtr/iO+JIVQbZMKEfaMpY6O+5ddHGNeiK8dLzWXt0DJ4TqtBz9CJ7BmUi3vzmlB/cw6mLR1F9QzmaoHpwfEdN/Cztoj4Twk5z8xOrpRa1IOi6tNfC9MFYpmpElXyJtB6fNnQMjuzLHpQN4clZhZqUFpZY20dh7jx4pMgUSKSJE1B2nRpSBD2gQDzeNgYgvmT1yypY8vpOsvplCOqO2qEcGxEG578eZ151SQghfg3+ycDUvdwJ0N7OpOk3xzaxd1Oj37nqDp7Lo7qtkt3azoNh1ozdUNnEu7sTONzzdk+zJTxdVdRZP1Msrm0ort7C5ynlOThrI4M82jI3IF6RlVdSaH12+hTKNK2SXeNsdVGkmLFBqqe6UiTvdVYvyAfG2r3w3rhNrpmiNjW+R/oQbVt9uyZVx2bwBM41RyHb/kypFQ3xkHengTFSUYCSzVMg19wwz2AFPmykNhcwef8Oq5X2MTOnjkxspmOPv0j5tVswLNhpxlXUtsw65+xqkM9lrxMQlxDjgf5EFhsGFsm2KtZNJsWDVeRqucflFALHX2ctNgc7cJQy4WcbX6ShtMysWKkNVO6ryHZwIUMLJ9MK6S+FP2ADL6Dc4eGavU3l12jyqAcG0ytQaGM2D2RyokMM+i4Pb0W7d6P4siIYsS6OYWa3UOZtGcg+Q3vx/cs4+pUY9KLvBRPH/EfpNfnouPc6lzr0Jv7Ldcw4F1f+oZOYEWRzTj+6UHzLc50UH8hjAl2HU7Z/pYsOOhEQeOzfMWPTW0Lsdv+Mssbqen807xYWicHC20csU36RakciZ77u7eSesbtnwhIPZ43znLDM4ykuUqTN0Wk/6aAR1w4dw8/k0RkLlYI7WMTQvwN3vv68eFDxOGWlCmSYmISjaGr/7dgHh+cQc92Ttwu0Z/meXVcWLEa3yod1CqsLr3UbZdLh748bO/MiJKvWdCkLwEjXejiM4q6q4qwuPk1us2Kx5DpJbkycjDbk/Zi3sgapDfXcW91a+xHhtBt2Uy6lkkVHli6a2OpNjIFyyZZMbzbFZo4T6HiW3Xb3c+aBdu6kjF8c+TPgR7V2Ga/h3nVbQg44UStlZkYVj8p7/WhXJ4/DLcyw2iTJzZhd9cwaFc6Bv5ZinTZs+I+cADBE7bSJ+dfiUc1UxZ1pvuWl5gH3WfvyTDK22WFJxfxr7+DE93u067eTXocGksJtWA72a8qy4pvZHjchfSY/JhSTWwJ31QrOkJTlFF3Li4xZnV8yjKLVZmmU/v6XLwaTKB78YQRP86IqLb0X/JzY0XXxnRf58mbY+NooZb9di3HcevDZaY3t6fnuifoA2+wY/cbSpfNpj7W43v3Ho8TJiWFIbz8rrOqZxfWZlzIJdfduLi4qG0DG5wHUjVTFQbPHkO9XEm1BFdQrDPRdMoU2kYRjoZQ8bruxpucuckSrXD8FfSEhlmROG1WsmaNqmUhZXyFsJ8ag/fF48RsutmVo8Wko2qMf/Z6x0i6d+lEy1GbufpSp/UKIf4qrzfe6HSh2tT3xY9nQ6qUycLb3xOOKl93Dh56S8q8hSlR2ZY4bidI0HcZjsohbnzwxrlTdw6WHEmTG13Ik6cO2/L8SetcoVzZe4G0eV8wePQdChd5xLBa/bhWdjrrxxnC0bBic7K0mMv6PubMLVuOblvUbbYaQDd3HSaeXSY291hJuuHDsUuq4/6unZy+sYZ2VSpSsaLaKpSl1a7c1DAM+xlkasGMgTl4efMOdy65sNWzMAXNn3Lnjju7Nl8ne4kk6nOP8Y2VlqbzV9LpL4WjgTk5Oi7l4L6dzKqXkTIjN3Fg5zwaZcpNnXoF8T+0h+dla0UUSIEX2XEuCzVs/bl0LS4dli5iYId2tGuntvadaZn4KD2HH+DJvbWMmHORO9smsetFAF7P/dTPIWrRqiD1ry/hsvKYGhBnmPqqLdt7vGJgnSs03tEfsxkOrMi9klZ3/6Dfk7bsWFaEbbVK0t81DS1mb2dZ2xyY+z/iiMsJTKo1p0LkCkkVeGoybcYexVf9/Qt6ehE3JTfF0llDmELu9suZ0CCFkdI3gL3dc9FwfxpKZYhcVimEBselyti1DLL9ejjEUEHmZWXmOXQr8qP/MD1B/gqpS9ur//EeXLzji6l5IHeOH8bD/wf7FGFqJVioJsVTq+swT0PJAmmNlu5f8NtAa4d9mFopVFy6lOYp1SX0T1nasjc+hS3YFzSAPU75/n9DFEIItu48xNpNu2nZpDb2lctgbm6mPfM/xHcP3WrvxW5FdY522EnZJa250W0GSrlkPNFXoL+jDQdmXyVdx67UzKimQ+BphtRdRXoHb2adLMOAEibYpHjHivmnCTR/zXW3MHIWTIVpYABZO69hWKkwzNOlI6FheNVuJClWTiGsW3Vc255laXVPptTsh/WCbXSNKB+14VU79syrwaexN5+9DG05m8vvPLjglZoS2eOrYfKB+673iFMoBwWbzGZ266y/Zpulu8HEar0wm7ObnqZzqdldYcbOFlxu3QD37gcYW8KSwJP9sFtWku3LHXi3oisdFh3l6vP4FMkRj0R2o/jjzWDmZ57N6PJaLiiv2dB5ECbTDzIob9Sv8qeOQb5zbkaVG505OfgFncqdx/HUWCxH2TLNtAUpHr2g/MDB1E91gzVLLxK/Wjvq5o2rLany20qPCmM4p/PhWWAC0ic2QV9iKHsdzlJ1WnKWzGmA2qXRcXZsDbaVPsNaRyPlr/qBTbJvg/eADfwR+XhgyEH6F1tFoZOH6J/76zfth0ubnIz1qY1t6kghF/aa8+peTxKHSmSy0PpUipKIcj2GUlevhu3EY3ibxeKn9iGVUJTcbZjbp/yPDygbArLeXZo2uMWCgKFs7JWTWB5zaTbSmtHVjtL1cT8JSCF+AUNATp+3KvxximRJcGyqBmUl2/+poPTd05WKI16QxeoiB/2LqFXdTY4mHs7lAZ50dfKhbaMXjHatzd75tTAc3Qo8PYS6zkVZN82GsaXnkWvvJtqmiFiX364/qHu8ATsmV/zq5JyI4VW7kSlY5dIOa+e6lL3SHdcul2nYPzYLtv5BxOFHw/CqPVvt9jK/hg06f1+CLeMR11yPXufJmnZ/8HqAC33V7a3f/l40OlKLzRPVHQ+durUK9icsblz+v4N8gSf7U2F2Ljata47v1Jo42SzEpcFZWjdwp/uBj8OrdiwruZ3l9Qx5oefxggZ08h/Hzr45MQ8+i1O1hRRY3xf/cUswaTuelvFXUL+dD6P3DuI7+fizAdmYzIPvkjNtCB4XfUlVJB0mT2+QeYQH60qvoVbN8zTbUIkd1Q/hcG0djsm1BSPxW+dIKdfmnJtpH/4fFnh8IGVnZmTLumrcXbcLr6y1aVg6EQf/LMaqIieNB6T3OloU2En1a2tpFulp/cO51Ch4mlaP1tL047k5n/iyrmVhjta9wqK6kYI7YD+9Si4hz971tEv1nVov+Corhi3mcuB35gkXimnuVozrVDz6Z22FB+Q9/lyTj6Wtz9J400gSzm3EtLQLmRbWh4aPfj4gF61w4dadB9pU1AxfHt2zi6M29a1LV26weuMuber7BvfrRJJE33zw4Qy/Zr2dJmlT31etShmqViylTX3Lef0OLl+7pU1FLXmyxAzs1V6b+taNW/dYsmqzNvV9fbq3Jk0qI7/QmkEjphMUHKJNRa1CmWLUrl5Bm/qWy7b9nDl3VZuKWvx4cRkxqKs29a37D58yZ9Faber7unZoSpZM6bSpb42cMA+f91+fKv+tkkXz06ievTb1rZ37jnHk+DltKmoWFuZMHNlbm/rWi5evmTxruTb1fW0d65E3V1Zt6suA/OhjUFarbIuZ2T8dlP7s6V6PY/XXU3VnM/ZWW0/L8y2YmrwLmVa1ZY2+KGk8j3I7UVnyx89Ky6XjST+/Hs7FN7Cg+iumVOvCg4pFMHkZglksBe8LLlxKWp8qhrRTwrDI35JR7Yqq2yYd18bYMSLlKja1S4PPinpUvd2blUmcaHjZgX5VEkUUBGHP2bHoOe0PzaeGjR9Hx7VlylnDutVt96PTnPTPRoXcSTBXZ357fSfusStTLrO6ZQ8LJihVQ2bNaUf2/8+evf4Zzs0bcbXjfqaW9mBUtQmkW72OGsdb0sC9OwfGlsAy8CT97JZTcvtk0p3cg0eAnktzJvGi3hBqpYhD+kSuDN5QkA19HtK4G8w62Jd4S+vT7t1o9g7K+93t6k/+NpiSqdlMDn2sIA8aKsgyzFET+86u3dzMUogPrld5yTuub1nEAsWGvA0aUTrZj0JFFebNhZXTeNSzGU20rqgE3nDDPXV2/vxqlyjk1SvepElNSmO7LHof/PxjEzeOoXrUcXfDRJy989OwVjT/98ICuHvAjfgTp+GQKKKWVLy306u7J51XdeRjIRt0cDDtb/szLmLy58SvTItiC1m28ySpTqWizopkmO7VnvtJHvcfc+nqDW0qaoFBQdoj496+ex+t9RiEhHz/OGl011MgXw7tkXH3Hz2N1rrSp02lPTLOcBJGdF9TQMD3r4297HaLwMDvf5YGWTNHHUQGT56+jNZrShzFjshH/h8Cov3e/Pw/aI+Mc7txB68377SpqBlOZPme5y88o/WaLC0jDeUYYfico/ve6tWurD2K2qvXb5g8cxkbt+xj+vgBJEkcsdd9/PQFrt/wCH/csXXD8OD+7XyOsn3LeU5cq87ms+6YX1ArxZdxqFBlNR/6XOF22Yt0dcjG4L3TqBxeYZzG6VJGqvVPgO7+ao4HlaCjXQ2ShFphHurK5HMODHZqTTY1LNEHQxLtcgvdTXYeiU+VWSHcPePM7CUfaDQjIfucQrC1tyTgQ8TvROjNnbgVGEbZ8LFVGyo4uVDB9w67F05lWZJB7BlRh9s9mnG30zaWmOWh1h/XKdV7Pn3LpfrxoaVo8D0xk0Wh7VhVzobAs+s5kKoeW5N7c2jXM2y7FwyvTgMv7uBclloMjuvNWU8f3rw+xQ7fYnS09FZ/b2MRcsWVDNV68njTTKzqryRXrGcs3udP5dE5flh0/GRAKgS/ucelS295H/SWh5cuYfYmGCXFQeas9MeueUqCA24SGqYj6IM/vjoTgsMMy/mzUy2Bx7qaYeFzh3s+7thfHaeW66lp0itt+JrVYhaTWIlJnNjwlr9X1Op4dOEct8Ky47piIZe1XoOwe648TVWT1MbeVcgLXrxOQrKkhv+2IILNzfA+MJKaY1+jD8xEvAde6FKliPoDi6W+Pv0tdkwfh7uV1hf0APe7ASwb70V8bfxV//QaYeWid+7Tt6wp2rwGkxr8gUfVOfRV/06jXd5/JZ5aYfxoI2pgOBHheywtzaO1HgNT9TP6nuiuJ7b1xw/YOJu4caK1rgQJIl/I+i3DBi+6r+lHlYVhPdEJyB9dKhAnjnW0XlPihPG1R8aZq6/3V723hAniExb2499EmzhfD+J9KY763qPzmn4UkKamptF+b9EJNQtzcxxqVKRpQzVYIq338tWbbN11OPxxu5b1w//93Tz3b+F+q+0csd1KywPDcG52idaToXTR9OjfH2blDBeOWOSk6KZVLDdLR/E0B7iUNiPJBzWgwpn3VJw0DZP1vZmQcjLLst/ibZmGVPJeS935GVjs0oM8WvGgU4PvcHw7Bu74g4YHU9F25FK6xl2Pg1VLFvz5eXh1fw+1kq1RFhv9W26fOMKRI/s4eOUtiUu1pN+fWYj9ZBeHfMvTOoWXWhjVYUS/QKa2LceBKm1oXrcOde1yYWQMMHr8zjBt9HUcpo8ho6kf+9cfI1v9QST13sfOu7lpYPOQ27f13N54jqy1BpPAPAHVOmTiycIj7HYcTtdmKQi2vMH4yqmp2uYQ0yfnpNPuLPBwFtt8yjMxx49/N35qiPX1sgbknepL6WwfuHrYm4yVcxLr9gks64ynfNactG1jSyK/NTQrcobml+ZSI9JI5kdRDrGuysn88oOJPf8QQ4rq2RflEKs/F9bO4dAz068u2FfwPb+UubFH83hlo88Hkz/ydKZZqUPUvrCSJuGXpUTwu7ucP+yHcNrEkkSFG9O5SweaVMjENy/dsKdWog8hQ0djn0CrIH32MWSgF23mOpLlYwV5fBx9/AZzdUalnx9i3TWYgupej+ua9bwu1IHaOc3xW+tIvb8wxCqE+FbkIdaogvGj6XNXfgrI/VsXY231/z2a9gO6a0yqPYI4M1eSfWE9dlTZRLsrLZgcpyN21l6ExNJxbfl0ntn3o0ZKBZ1NNtJcHcuuwmOp4fuEZKXS4j5tJMdyD2VG19y49qjLsfo7mFzoMkMqN8C90wlcOmRTtyM6ro6pysiUzuHDqxGbLh23p9Sif+wFbP0jQ0Sf/3562G/Dbu98asR+zNaJ83mSoyH1cz1i+fwTvFG3uf7uuzkXx55KGc1QwvSkqT6U7nnusnr+DoKr96eLbVJMAy+ycvwJkrX/k2rptA3lj+hfsrtXQ+ZmnMPmXgWweLiMho2v8cfhmeTf1Yzy880onUPdkQ57woEdKZluuIGB4b9Q/4SFDZpzrWQJXlxIxqA5lfE6epXzKxfzus04ip3eRlj9FmSLn4rS+aNR5RoCMnpClJtT7ZSyYy8pQb7rFMeCvZQDHwKU4wMKK/XHLFFG9uqt9OnTR+nTs46SJ34RpUkv9XHvnkqPsVuU+yHaKlS+a1soeXrsVT6EPFauur1QfA/0VvLVnK143J6pVEvfWtn41jCXn7KtU0al7uIXSmj4UtFheC15lYKDTqqPvuW9tZOSrepUxT3Sawn3YZ/SM18DZfF9D+Xwgj5KzZyplTwO/RTny++1GTQh7srGcUOU4cOHf279HZTMicopXYZF6hvqpAx3Vj8jbbFo8V2vtKo8RrlsZCHfNS2UymOvqZ++EOL/a8uOg0qlWm2VWQtWK15v32m9xk2bs0IpY+8Y3gICf+ov+i9Qt6/z6iqVBh1X3od4KFsnL1JOvnVTJtZqqazx1GZ5v0PpXLanut3VpgNOKoOqdFK2eocqrw5PVhqXra4M3HYvYtvzZpvSqXI/5Zi2MXyzt6di23CxcsewIQm5oowuV0dZ9DRi6+q5Y7jSvHlzpVwqKyV/3dZKmzZtwlvr+gWVOCnKKM16L1euGZb7emMc+lRZ3ryOMvXG97dOQdfHKjlprGz30zp+JPS5sn9IeaVQ63XKfb+LyvT6hZQsqfMqHTc8UF/CC2Vlw6JK3+MRb+z9vj+U3I1WKW/Cp0KVl+r7zE06pfbwrcrNd6+Vay6jlEbFyihd191Sc8FbOTO2jBIvbz/lYMQCP/QTFaQ/u7sVw7nIMdbXP4xj6XO0cB2P9agyzE41nQ6ZP6CYx8JE58q0Lm5UWdiRvLHC0JmnpkS5vCTWotpQQZY8VJjOYatZkWQsR/qkxu2xPy9WdWa06Vj2N75J3/mhODq1oHCaFCSLF926yYe1zTLgbHuVXR/3gD5S9yqcW5VnUc6NHBpc5Muzqr4+SefddTbN20xg3cE45vr4s4O5vnY8q6+HfHmbuw9XWbPyPZU7lyN5pFFVvS4pFXr1wP57J/184q1Wh9VoMfk56YtmoUDrOSzqmAfz1zsY1HISxx66cVFfhwW7ltIuGkMCQoioPXj0LPzwQ1Qnk0X2d1aQXoeH0HBkKMO2TaBiInUztLELZYYfI3n9uWweUxHDq/Xa3JaaRxtyeE618BEu/0N9sFtbkp3LGhD/xWUufchBsUxvWftnC2a5KuTvuYQ5LQwV45eCzw+n3PCkrNvVLfxGAD6Pb/I8yAJLY5srRa9u/eKTJYMvq7v1YPNLy/ATciKo2/fgUGJZWnze3oYFE5KzM6sm1SHiiLSeZxs70f1OZ9YP/Wrba5Qvl2a1prurPfMXdSR/XG9unb2LWfbCZE2kvhP9K66dekL8EsXIoK5MH+iDb2gcEtpEvMtgt93s1ZfEznwDLetN42XpDgxy6kaNrNrwv+4GM2o15XaXwyxw+P4xc4PoB2TgKZxsnYi75CBO6U8yfew9So5phW5UWeZk3cOGttoP++4Q6ztOj6hJ2ZHPsBs+jzkDapAp6CqrR3bH6VRh5mydSu2Ed9g4rDP9T+RizMpptMitvrHgy6wavRb3MIvvHDT159r62Twt2o+amSPmCgsJJm2tIdT2GUKNDg9of2wHPT6FnuaHZ7GqvyDqL4Hn5f1c8oqFug/wifL+IKOGvqHl9KbaHScMFPTBFmSsUJbscayx/M2jMkKI3+PvHWL15907cxImjPgZ+tce3PRPRI5MiT8F3Lt7l3hqmYt8aSMO3uj83+KjxCOpFg4Rgnl1/xmxUmUmWbSP8fxOgTy6dh/LPHkwXN7993mH19vYJA0/p+VLuuBgNdQtfzy8qopmQOp5takzZSalwvn4yIibj3sdZMqwtZy76krc3udY3lA7IeKdM02LnaHZlfnU+iYgdTx0GcdyfQP617Xk0PhhTFm2n7dFejFtWj+qGXYJDPSvOTqmCc0252PJ4RnUSPCAE9vO89pUfVPfPw/kC2G6IGzyVCHtwzVseFKAHl3KhV839AX/PfQorgbkPhc6pjXykenuMt+xIUuf2GD1zbk3oQQFhmHx8f6wnyiEBgRRbNhxZtUxciBWCPE/L3JA7tuy6Icnj4n/nmgGZCAeRzZxKqQELey1uyPoPTm0cB4XzEpRv4Ud2T6ewPb2CHOmPqTY0HYU++4ejJ7XJ9ez60Nh6tnnCB9C+IL+KWdP+5CnbN5vT7j5lQIvsGKcK2m6/kHlr+7yI4SIuWbMW8WWnYfCH0tAxkw/dRarEELEFBKQ4q9esCeEEEL8p0lACiGEEEZIQAohhBBGSEAKIcSPyKkaMZIEpBBCGPN3fUmy+J8lASmEEEIYIQEphBBCGCHXQQohhCYoKJhjpy6EP54xfxUBARFfYfZn5xZYx7YmXZoU5Mn5+QuYxX9bjAvIu/ceEarXh3+nYNrUKbReIYQwnIuj0L3fWNxu3NV6vjRr4iAK5MupTYn/uhg3xNpr0EQ69xzJ3MVrtR4hhIhgYmJCm+Z1takvFVSDUcIxZpFjkEIIEUmhArnImzubNvVZm+Z1tEcippCAFEKISAxVZNuvqkipHmMmCUghhPjK11WkVI8xkwSkEEJ8JeJYZEQoFsov1WNMJQEphBBGFC6Qmzy5stI6ipN2xH+fBKQQQhhhqCKH9OtMgbw5tB4R00hACiFEFFKlSKo9EjGRBKQQQghhhASkEEIIYYQEpBDiFwvk6aNnBGtTXwi8gfPgEbjcDdQ6jNM/3cuY3jM45aV1/KP8uLy4H71nH+bR91/2J3rt38h0t1bQp7363m8FaD3G6Hj55Jn6CYr/BRKQQohfy+sQE2tWpc2887zTuj6xSEya2GfpXasdS9z8tc5vmdokIcHDCdjVG8kxNST1L0+xbtESli5d+k1bPG82G85985M03qxplYmqky58Dh3dXWbYp6D2vNtqHEVHbNIWKoDVwa6UrdiJuSeffXe5wLOjqFa8CcPWXOD1x6TUP2PnzCkcjVcM2wwmBAYGRmr++Hi9Izw2vQ4woVpxKnVdxgVvdV2nR1I+cxay58hBjiha9szpKNhnX8Ty4peKcTcrr9GwC37+HyhVvAATRvTWeoUQv5L/zbX0bTGI23ZzWT6qJhnNtSfCeXNmels6n67BlnUdyPLFc5H4XWVO0xo4F9/O0eZPmT7rJO/Mvt6n1/N47wx0fb3Z1iah1heZHxtb5mRHjVusbmyj9b1kYe3y3Oh2hVlVY2t9H+l5tm8O806+wcz0qy9MVvy5vWMV1zO2oEG+eHx8VgkNJjRzPYa1K451eI837tuXMnn0NM6kdWLtmlbEWt6GppMfkDJDHLxunuZN0tLkSmqmzhvI8yuXsW6/i2NT7Uik9uhenGT+gC6MdS/L9FHJmDPehFlHh1PE0rDuYFyHlcL+RD12bx1MafUt6/xe4xUYm1TJ4hpmEL+QBKQQ4rfQPdrNxEWvqNUhLy/c1DLQInK46QkNNcXMkBEqJSSAkCSFqVE6A+Z++xndfitJ+06mQ1Yd7+MkIlFUIaoG4LY2WVhVwYMtLeNpfZGpAdkqP3tru7G8/scAUQPSoTJ3el5kWoWISIvM+/IuDtwPwco8egNsii6QgASFaFQlO1+8zHdu7DqnJ/PbWdQbHUyfjUtok2IPnYo2xbXWZg7MrIHZgX7Y/fmOAYeX0CStqbagSu+J62434qdwpX3PMGZ+DEjf/fQsMRCL2UeZVClBxLzit5GAFEL8VsFuKxgy25Xg2JaYBN9h97o3FGlVmuSRCjQl+APk78DELmoV5reZlhlWU8FjK20MJdV3GQlI/9ucPP6QgPBqU8fFGe05U2YJPQp/jC9/jo7uzZPG82mVTQ2lMB3mqYtTLl9SPkeUnqf757PkvB+xvwj2z8LUYLQp2p4udmkiLReZnldnXfEukI/kAaYkThzMiWF16P26JlUfrOVRo2U4pT3PyaAKtHfIpoarH08eB5A6ffJP6wu+NIaK3fVMX5aKOY6LuBPykvNukK9EWgy1rz44iBRNF+LSrxjhBab4pSQghRC/jP6VGyfdvYllYUJoUCBxslWieIbPdZX+wWxqN3zBwFPjKfNt8RbBbwutsqylsscmHOMFcv/sSR4FmUc6YUIh1DQp+UvnJZnptwGp99zJhEHbeWphKE8Vnh5dwv2s7Smf5mMih+CxZx1vi7akRFK1Tw3IxJUGMqJx1kgVoJ4nCxpQ7URJBtZIbeRkjTCe757A2bJ72dQ53bcBGfiQA/OGMmiFOb12LqFF2jecmvsn3bdmZvL6UZQL2El/xxE8rzeTGd3LkUr9wfoX62lrOxS/TvOZ2bsyadW+4IujqfinCTNXJ2Zk5cu0ODCUkp9epJ7b8xozJt4iDjoVkID8DaI3hiCEENEQ+uo8W1atZOWqFUzo2oFl1748lzUsKJiQ+PGJH+0tj45z0x3oMG4Jy5YtC29LZ/aifr+dvArTZvmKafJaDF62hAULFqhtCq1KpKdkm6natKGNpVHBTFTsNiNietFSxn4RjhFixTLBKkkGcuTMSc5vWg4yJLHCJNZXb0TvxeUNo2lR3o7ht0syff8C6rx3pnvV0rTanZWxK0ZQObkp5hnrMGXdJAqc6IhtlQ6MWbqPu9ZNmL1tOKm2Nqey41zCzzvSh6o7A7EwNfwcvxscWBnxGUS0Fey84ml4obIh/03kcxVC/DKWBdoza9Vyli6ZQOP88Yht/eUmJtTTkxd3tjDEsRGNGhlaQ+rVqknfjc/Uesg4U4s0VOq+AGdn5/C2dEQDclnEQjt8+duEJshG9rd7mDd7NrO/afPY66MGZcJQbW6NqRn+j56QrJsL69skwX37clafeUVo0nK0qpWaJ3uXfgrqxbvvE7/uBKbUseCplzkJ1AI4Xr4WzNmznd55rDBXS8KwEHWHwsoSK3XVJqY2JE6ZkpSfWgqS2Ejd+DtJQAohfj29umHXmWNm8eWZoL5PnqKv0oURQ4YwJLwNpErsSzz6YB3Fcbx/iFoJBmVuypBhTgwaNMh4cxpE00Ifz4z9KCFlByxmmmN+YntsZeruR4SZJCB/+aIkVUIIjXRAS3l+UK0YPSncfS4LB1Yi5ccPIFF+ytUuRY7Y6st4/x7f2PGIb6IuaJOVCq060anTx9aW6nkSG46TaQuKXy1GBOSFy+78OWB8eDMcfzQ4c+5q+HTPgeN54+0T3ieE+FVC0IWYYf5FmReA+/WbZC5Sjvz58pEvvGUjsZUZ1tYW2jz/T/4XcZkzj/nz52ttJSfvveXe8RWR+tZx7vFbbh1YFqlvPmtOvvhcxQZeZf2YEQwfNpShQ79q/VpSKXsh6o/YxTOTuFEGu1ksU2yyV6J158507tyOKuxj9LpX5G5imO5Ma7ucJDI1Mjzqc5AZTQez9rEOf7Xi1iVJStzAAAIer6JD3ixkSZ9SrSTTkyVLLupNc+W9vz9f1bHiF4kRAZkvTzaePH3BFbdbWk8Ew7S1lRVJEsnp0kL8UmEhhISaqwGp8HBjb/o6P0avhs7RE/EpVTp1pFBRwitNK6svK83IwvQvODy7M46OjuGt3YhN3NKFGR+SVYIJeO+Dr6+v1j6QprYTdkkj94WQrUkvyifw/9zn8w7fgEgxE9eeEVu34rJhAxu0tnZWH2rntiFIyUu37Rc4vX4A9pmiO8Sp48kTT0o0caTUdzc3el7udWFvilIUTxXKvXsPSZcpPZbZu7Pm5hWu3L3HlSl2xKk8iSv37vPIV+HSqBLa9ZfiV4sxZ7G6bNvP7IVrtKnPlsweRbYsGbQpIcQvEXyVcVW74duyMhcnnaHS0vV0CRxL+fHJWbW3P/k+5cpLltSrjHvnC8z4eNH+F2exBnD35GEehsSNdBmlgk5JTIFy+Y2exfq1tyfH0qDZHsqu3sHIcol5u/dPqg58S6s5U+haJsWXFWDgORYOXM51rDD7KrOV99fYujMA22YlSfZVaaGEKuRoNoEupT5H1Tvn5lS40ooz06oS23sfPSvPIJ3zTnrnjjgdKPCkExWmp2ejSyfSfXwRujvMqm2Ha/MzODd+zwz7Gnj0cmNB+as42dbnsuMuVqabS9EddhyqdoBW20uycHlH8n19vwPxS8SICtKgdvUKJE4YX5uKULp4QQlHIX6HMD/8vM8xsfcO8k5dSv+iL1g1Yy952zUhd+SiS+eLX0A84tlENVAZm2xlamFXqQIVKnxsFala0RCO2ixR0vNs/wgaNlhE8qHz6KuGo0Hiyn2Z0lLPvGplaT7rDF6RS1GzFOSvWpOa1atT/etWKS8p0xfBvsbXz1XDvmpF8qWIPJ6sVyvSALU61hEW6MFGpyGctO1MoQOOVGkxiHk7rvHWJBnZ08VBLYY/8T2xmEWP69HGIRWh17ey5U5ZKhaLxeUFI9iQYSQzehQNv/7RsOlOUb0DDm+H0bTPVh5HdYaT+P8xVJAxxcat+5Qy9o6f2h2Ph9ozQohfKfThCqVx0jRK/UXuSoDirZweX0XJbD9TcQvSZvjow2GlT157ZaZHqNah8t2stExWX1n1Xpv+rvfKhuYJlbpfzxz0SNk/ob6SOU5OpfUKN8VP6/4sVHl1cppSN52NUqj7BuXu16/LiBD3yUrV8uOUK9GYN1zIa8V99xyle5WcSsHWi5XL6ksMfeehHFs9QelSPbeSNld1peuUzcoVzxBt/pvK7GpJFdvxV5SgkLvKkvqplGw9dilX1ndW8qeppcy7EfGDfTe2UtK2WK/4qo9DH65X2mRJplSf5aZoaxG/UIwKyKDgYKVO027h4Thw+DStVwjx66kBdOeO8irggbJ3pL2SNl1DZcnNj8kSonhsHK506dRBaVYhk5Kw5GjlTID2lIHvJsUxcb0fBGSAcmp4WSVdusQKVmWVSRc+p9brEzMVxwI2ClkbK9NOvFRfSdSCPFyU7gUSKuUmXYsyYN5e3KosW+msLB/fWMlZcZLi9oMkClHX6dSkilIwbTwlWYGGitOq84rnNy8iQHl0fIkysG5uJVHyCsrYk35K0PkxSsnkdZUlD30V14kVFJtEdZRFt58rZ5cOVcZueaCEeB5QpnTtpLQql0ZJ12WX8kFbk/f5vcqRB9FNbfEzYtyddD4ei5Rjj0L8DfQ+3D20jUtxa9G0dMQQp4Hu7hamO9/CKltRqtSsSs7I9xkPPM38IRfJPuRPKhq7/7gm+P5pjjy2JHvBgmRKGGm8NdCDXesuk8qhMYU+/8go6V/d55FlZjJH8bN0d5bStetGXifLTJEG3elXL+cP7lrzjjOrV3MvWSVqVMpF4u8OBfty97gblLAlm6We109eEDtdWqy93Dh6Nw7lSmf+fAMD/Qv2z1vIFbMCVKlbm8IpfjjGLP6fYlxABoeEMGfhWvp0b631CCGEEN+KcQFpEBYWRqyvbxElhBBCRBIjA1IIIYT4ESmjhBBCCCMkIIUQQggjJCCFEEIIIyQghRBCCCMkIIUQQggjJCCFEEIII+QyDyGEMOKa+x0ePnoW/rimfTnMzL74cksRA0hACiGEEdPnrmTrrsPhj/dvXYy1VXS/+1H8V8gQqxBCCGGEBKQQQghhhASkEEIIYYQEpBBCCGGEBKQQQghhhASkEEIIYYQEpBBCCGGEBKQQQghhhASkEEIIYYQEpBBCCGGEBKQQQghhhASkEEIIYYQEpBBCCGGEBKQQQghhhASkEEIIYYQEpBBCCGGEBKQQQghhhASkEEIIYYQEpBBCCGGEBKQQQghhhASkEEJoAoOCOXTsrNZctV4+9d2++0DrETGBiaLSHgshRIxm2Bx26T2Km7fvaz1fmjVxEAXy5dSmxH+dVJBCCKExMTGhTYu62tSXCqrBKOEYs0hACiFEJMUK5SVXjsza1GdtmtfRHomYQgJSCCEiMVSRbVvU06YiFMibQ6rHGEgCUgghvlK0UB5y58iiTanVYxTDruK/TQJSCCG+EvlYpOHYo6GJmEcCUgghjPhYRcqxx5hLLvMQQogoPH/hSepUybUpEdNIQAohhBBGyBCrEEIIYYQEpBBCCGGEBKQQQghhhASkEEIIYYQEpBBCCGGEBKQQQghhhASkEEIIYYQEpBDi9wi+wsI/uzPr6Cv0WtfP8L/vxu132sQXdNzft4DZG8/j9VdW/MsE43XvCjdf6LRp8V8jNwoQQvwWnls6UnqAP10nNiWLuUKoPgFx/Y+w/1ogpl/smivozfLQbFhLCllqXfonrHIsy7y0C9k+zo7keOJ6+AHpK5UkpWkwl9S+XvpJHBxaDMuA6+w/FELBGoVJZqouG3CU6b038NDSilgmEav7nrCQIFLXHsUA+2Raj4EPZ1bN58RrCyzVF6voQwgK8MfXx5s3Xq959fwJD+7e4s7zDyStNoU9G3tRKK62qIH+Mev6/sFqDxO++xL0NpQfvIy+ttZah/hfIgEphPj13u6nr/0gHpezJ6tFMLe3L+Cxww7W1vTj2is1NC7MYMD9GkxzzE4sn8NMmG7NxNPjKaPlhN+pYVTvH8roPeMon0DNEc/DjG7eHdeKC1jjVJwn46szwGwGu/tl4fbsxjTcno8Zy0Zin05NSN1tDm+5jp+VRUQ4hVxgdpeL2C7sQkGz8NV/wRCQsXNWxy6PjdZj4MuGltmZYdoVhxyWmFlYYGVlhXXsONjYxCd+wkQkSZaS1OlSE1/3nqA4yUj4MdzDvWaxQxnON15L11yG1DYmgD392uA18CrTK0lA/i+SgBRC/Fo6D9Z0bMDcVDPZPbY8JqeG49A/iKG7JlI5UfgM3JxSk666iewbVACujMNukBULdvYmh7n6tN85JtStxqTneSmeMU54yIUpeek0qyLn2vTjWcd19HzeAyezaSzJt54WfR7TdstKWmczLPyt4HPDsO1rxeJDThT4IsS+x49NbQux2/4yyxtFDs7o8mKJQ3bmx25G6aRRHcnScXf3IXIudmN6xegEpJ7Xt89z+3UYSbKXIFfySMEb8Jgrlx7hZ5KQTIXzkUby9peQY5BCiF/Hzx3n7o3pvvoVPmem0qZObaq1GMWNgGvMblWTfi4v0QdeZ8deH0qVyaxmhB7fex68SJSM5IZ887/Bmt5dWJV2NmdPbGG1szPOzitYvvBPymeyY8jMEdTMklDbcCnozdPRdPJEHKMIR0OovHW7zuscuckS7XD8FfTow6xJkSUPefJE1XKSLr76HsKiW6P4cvfwVDpWsKXZlOP4a70Gr7YNp1P7VjQb7sJlz3/0wOx/ilSQQohfRu95kQ3LjxKquDL9VSs2d3vN4AZXaLi1D2Yz67OuwBqa3+pI/2cd2bkkF+vtKjLqWiqazt3FYscsmPs/4ND645jUbEmlFF8OTQYcn0TbKacIUEvKwEeuuMUqQPF0Vmp5GUaeDqsY5xBenn4lgH3dclB3f3rKZY6j9Rko6IJsqDbBmb4ljJVbhgoyP85Z59G9qJFx2cgUPUEBkKZUZQqY3ufC3feYmH7g1tED3PEz/cExSEhRvBbFU4URYpWe4nlTEtWAbDi/NTjWPIR5XBOqLl1GkxRqn/4xSxz741c4FnvDhrC7X26i2l0QP0cCUgjxy71zbkaVG505OfgFncqdx/HUWCxHlWGGWTMS3n+J3eBh1E96jVWrLpOoensccsfWllT5baVn5QlcCPXhWWAC0ieOhVJiMNvtjlNxdmpWzHAgvjYrhHBqZC0OV7/ECmNDoTp3JlVthVf/9XTJHil6gvbTp+hmyl3bT88sxiLJD5c2ORj9tialUkWKOOU1FzbfIlmdcqSPlJsKKajSbzAOQavpP/4o3qbfjcVvqSFrXqgzs3va8t3RUUNAOjygecObLNENZ12PHHBnFs3GxmNclYN0feUkAfkLSUAKIX65d86NyTz4LjnThuBx0ZdURdJh8vQW2cbeZ3XhpVSv604b52Ksb3CO5pdW0jiptmAkfuscKeXanHMz7THEZ8DhftguyMGetZW5sXYf73I4ULd4XHZ1Lsq2iueNHyt8u45mBXZS89pamkUqMPX3ZmBf4gqdHq2kQeSzTz/xZX3LIhype5lFdSPN4L+XHsVXUujIelp/72sig6+yfOgiLgeZfb+CDNNhUbA9Y9sVJlojwOEB+Yje6/KwqN1FWrgMIe7MJszOtJBpwb1oIAH5S8kxSCHEb2BKpmYzObRvKPa5GzL54CFmNsuk9oZya/du7mZLjf9Fd7zw5vq2pSyav5Fz3tqiPxL6BtclUzn6Ovb3hyNVgTeu4p46J9kjj66qQl568jptalJGtQL9e3w/WBM3jmETqePOhrGMWLgHd9+wiOd/JCwAjwNuJKjpSMuWLcObY7U4nD8YQsnmEdOGVifJLfbe9ieaa/0sQVUcC1/BefdJtpxOg4N9su8HsfhLJCCFEL+BQvCbe1y69JT3QW95eOkS994EE+aznzmrQrAvk5QAv0B0+hACfH3w8fEjJPzcEn929bOlRJly1Bh3kHtbBmFfriwlijRlyfOPMWKCiVkSkiT5UZ2k4+H5c9wIe8GZ5QtYsOBzW77Vlccp05LWQpv1ayHPeeGZhGRJDQkahM7SEp/Do6ldogubX77h+SOv79/8wHABpv4WO6aNZcyYMeFt7MxduN8+wuJxEdOGNnW7O3qTvxJt1hRtZs/r0d05kaMuFeJp3eKXkoAUQvxyOp0Oz9NrmDxtM1efuLJmymScT70kwDOYbP0mM6F/T3q2tiVj4txU69KH/oPaoWamKi41J5/C9eRxdjtVIUu98ew7fgLXi+tom0rbXCnv1UC1wNLyR5uvYD6ktGN0/YwE+vri+6m958m9h1imTkWiqCpIXw/uvkpDhvSGgU8b8tTpy4yNZ7l6cDjl4t5iafMSlGo2mGUnHhEQscSXwvQosbJQpV1XunXrFt66tqlMjiylafpHxLShdaiajVh/8SiXefam9O3XnV5ty6ifmvgdJCCFEL+Yjrc+/uRsMZmNa3pSLlsNhqxbz8g6GbCOY0rAtS2M7duXvmN3cOPFGVYOUR/37U3PSbt4aqws0z3B7forlNAQgnQhBD68itv7LGTPZAgvtVIN8iMo2Njt3uJStPkgnAb0p3//yK07lTJakE4NyKhq0Heup7mcOT95vzqsGU9dJolNGYYe3seYMh9w6WhLyXpObLge+aILlVlCCjauStwbpzl16lR4O33xHm/ePebqmYhpQ7tqWZ6mhT5etvKzElOqxR/UzilHHH8XCUghxC8WzIMHT0iZOg2WaoApoWGfjrHFsslC8QqVqVK1KlUr5SVVgkwUq6I+rlKFSkUyYPNVRaf432ZZx/q0d3ZHKdCeRU4FODd7BS9qN6D49XE0a7WQBIPOMrPO5/Naf+wDz589116fEfqn7HY5QNJyZckSRfaYWGWlSpcZ7Dq9i0EFrAizjLymYNxcXLjoG0pwcHCkpkMfFkpI5D6dgt/lY5zw0hb9Lm/2TJjJ7pMLaFexAm0Xu6u7IurLfbWNfna22I3ZyfGlU1nnIfeG/VXkLFYhxK8VeAonWyfiLjmIU/qTTB/3gFKjHQkZVZb5uQ6w1jFhxHyeS2lY5QYdXadRJdJVHhF8ODOiBmVGPsNu+HzmDqpOug+XWTuiO05nizFv6xRqxb/F2sGdGHKuEBOcJ9Eom7WaTZdZOXIN7mHmUZ/Ao/hxZe08PG37Yp8+Yi59SAiZ6o2li60FT7f/Sc0OD2h3bDs9cn2VkD88i1WvBl8Ir64c4oqXCWaRDi8q7/YxbOR7OkxrTLpPpYmi/mxrslQsTSZra6yjdSqr+LtIQAohfiE9rzZ1psykVDgfH0n4NfheB5kybD3nr54jYX9XFn68bOLlYuqpAdnp/AzsvglIHQ83jWd5aH3617Xk0PhhTF62H+8ivZk+TQ22DFqS6F9xYFhDWu0ryapDk6gS9wHHt57jtaklP3MpYpguiPj5G1IlRzC39yzD5WkBunUqixbln/nv5I/Cqyh8zIV2KbW+yHR3md+8HgsfxuHbQ6Rh6EIUzCy+vnmAQmiACRUmHGVKjW8+CPEPkoAUQvxCgXgc2cSpkBK0sM8acYxPDbGDCxZw2bI09ZtXIYt2Jbz+1X7mzPXEdkhLCn+3ctLjdXIDOwMKUc8uBwm03k90jzl99gP5y+b6/SerBJ5j2ZiLZPizMxXDvzpE/JdJQAohhBBGyEk6QgghhBESkEIIIYQREpBCCCGEERKQQgghhBESkEIIIYQREpBCCCGEERKQQgghhBESkEIIIYQRcqMAIYQw4pXnG7zfvQ9/nCNbRmLFknoippGAFEIII2bMd2bLjoPhj/dtXkjs2No98kSMIbtEQgghhBESkEIIIYQREpBCCCGEERKQQgjxIyY/8eWS4j9DAlIIIYyR8xdjPAlIIYQQwggJSCGEEMIICUghhBDCCAlIIYT4ARM5SSdGkoAUQggj5CZjQgJSCCGEMEICUgghNCEhOu7eexTePO4/1nrBQ+vzfP1G6xExgdysXAghNGFhYTh2HMjT56+0ni+NHtKdcqWLalPiv04qSCGE0Bi+0qpVszra1JcyZ0xL2VJFtCkRE0hACiFEJJXLlyBt6hTa1Getm9eRs1ljGAlIIYSIxFBFGsIwskxSPcZIEpBCCPGVSuVKkC5NSm1KrR6bSfUYE0lACiHEVyKORTqEPzZUj+VKS/UYE0lACiGEER+rSKkeYy65zEMIIaLgfsuD3DmySEDGUBKQQgghhBEyxCqEEEJ8A/4PpaWgHk3VV5sAAAAASUVORK5CYII=" alt="">
相关函数
定义和初始化
静态初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
函数动态初始化
pthread_mutex_init()
函数原型
int pthread_mutex_init(pthread_mutex_t *restrict mutex, <br>const pthread_mutexattr_t *restrict attr);
功能
初始化一个互斥量
参数
mutex:指向要初始化的互斥量的指针
attr:指向pthread_mutexattr_t的指针,用于设置互斥量的属性
如果使用默认属性,可以设置为NULL
返回值
成功时返回0
失败时返回错误号
锁定和解锁
pthread_mutex_lock()
函数原型
int pthread_mutex_lock(pthread_mutex_t *mutex)
功能
锁定互斥量
参数
mutex:要解锁的互斥量的指针
返回值
成功时返回0
失败时返回错误号
pthread_mutex_trylock()
函数原型
int pthread_mutex_trylock(pthread_mutex_t *mutex);
功能
尝试锁定互斥量,但不阻塞
参数
mutex:要尝试锁定的互斥量的指针
返回值
成功时返回0
如果互斥量已被锁定则返回EBUSY
其他失败情况返回错误号
pthread_mutex_unlock():
函数原型
int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能
解锁互斥量
参数
mutex:要解锁的互斥量的指针
返回值
成功时返回0
失败时返回错误号
销毁
pthread_mutex_destroy()
函数原型
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能
销毁一个已初始化的互斥量
参数
mutex:要销毁的互斥量的指针
返回值
成功时返回0
失败时返回错误号
<font color="#e74f4c">注意</font>
在销毁互斥量之前,必须确保它是未锁定的,并且没有其他线程正在等待它。
互斥量属性 (pthread_mutexattr_t)
pthread_mutexattr_init()
函数原型
int pthread_mutexattr_init(pthread_mutexattr_t *attr);<br>
参数
attr:指向要初始化的互斥量属性对象的指针
返回值:成功时返回0,失败时返回错误号
pthread_mutexattr_destroy():
函数原型
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
参数
attr:指向要销毁的互斥量属性对象的指针
返回值
成功时返回0
失败时返回错误号
类型
pthread_mutex_t,不透明
死锁
场景
有时,一个线程需要同时访问两个或更多不同的共享资源,而每个资源又都由不同的互<br>斥量管理
当超过一个线程加锁同一组互斥量时,就有可能发生死锁
定义
两个或两个以上的进程在执行过程中,因争夺共享资源而造成的一种互相等待的现象,<br>若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁
常见原因
忘记释放锁
重复加锁
多线程多锁,抢占锁资源
读写锁
场景
当有一个线程已经持有互斥锁时,互斥锁将所有试图进入临界区的线程都阻塞住。
但是考虑一种情形,当前持有互斥锁的线程只是要读访问共享资源,而同时有其它几个线程也想<br>读取这个共享资源
但是由于互斥锁的排它性,所有其它线程都无法获取锁,也就无法读访问共享资源了,但是实际上多个线程同时读访问共享资源并不会导致问题
定义
在对数据的读写操作中,更多的是读操作,写操作较少,例如对数据库数据的读写应用
为了满足当前能够允许多个读出,但只允许一个写入的需求,线程提供了读写锁来实现
特点
如果有其它线程读数据,则允许其它线程执行读操作,但不允许写操作
如果有其它线程写数据,则其它线程都不允许读、写操作
写是独占的,写的优先级高
相关函数
定义和初始化
静态初始化
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
动态初始化
pthread_rwlock_init()
函数原型
int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
功能
初始化一个读写锁。
参数
rwlock:指向要初始化的读写锁的指针
attr
指向pthread_rwlockattr_t的指针,用于设置读写锁的属性
如果使用默认属性,可以设置为NULL
返回值
成功时返回0
失败时返回错误号
读锁定和解锁
pthread_rwlock_rdlock()
函数原型
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
功能
为读操作锁定读写锁
参数
rwlock:要锁定的读写锁的指针。
返回值
成功时返回0
失败时返回错误号
pthread_rwlock_tryrdlock()
函数原型
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
功能
尝试为读操作锁定读写锁,但不阻塞
参数
rwlock:要尝试锁定的读写锁的指针
返回值
成功时返回0
如果读写锁已被写锁定则返回EBUSY
其他失败情况返回错误号
pthread_rwlock_unlock():
函数原型
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
功能
解锁读写锁
参数
rwlock:要解锁的读写锁的指针
返回值
成功时返回0
失败时返回错误号
写锁定和解锁
pthread_rwlock_wrlock()
函数原型
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);<br>
功能
为写操作锁定读写锁
参数
rwlock:要锁定的读写锁的指针
返回值
成功时返回0
失败时返回错误号
pthread_rwlock_trywrlock()
函数原型
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
功能
尝试为写操作锁定读写锁,但不阻塞
参数
rwlock:要尝试锁定的读写锁的指针
返回值
成功时返回0
如果读写锁已被读锁定或写锁定则返回EBUSY
他失败情况返回错误号
销毁
pthread_rwlock_destroy()
函数原型
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
功能
销毁一个已初始化的读写锁
参数
rwlock:要销毁的读写锁的指针
返回值
成功时返回0
失败时返回错误号
类型
pthread_rwlock_t
不透明
生产者消费者模型
条件变量
简介
允许线程等待某个条件成为真,而在等待时释放互斥锁
当其他线程改变了这个条件并发出通知时,等待的线程会被唤醒并重新尝试获得互斥锁
类型
pthread_cond_t
相关函数
初始化
pthread_cond_init()
函数原型
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
功能
初始化一个条件变量
参数
cond:指向要初始化的条件变量的指针。
attr
指向pthread_condattr_t的指针,用于设置条件变量的属性
如果使用默认属性,可以设置为NULL
返回值
成功时返回0
失败时返回错误号
等待
pthread_cond_wait()
功能
等待条件变量
函数原型
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
参数
cond:要等待的条件变量的指针
mutex
与条件变量关联的互斥锁的指针
<font color="#e74f4c">调用此函数前,线程必须持有该互斥锁。</font>
介绍
当线程需要等待某个条件成为真时,它会使用 pthread_cond_wait 函数
这个函数会自动释放与条件变量关联的互斥锁,并使线程进入阻塞状态
当条件变量被通知时,线程会被唤醒并重新尝试获得互斥锁
有时限的等待
pthread_cond_timedwait()
函数原型
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
功能
在指定的时间内等待条件变量
参数
cond:要等待的条件变量的指针。
mutex:与条件变量关联的互斥锁的指针
abstime
指定等待的绝对时间
如果在这个时间之前条件变量没有被通知,函数会返回
返回值
成功时返回0
如果超时则返回ETIMEDOUT
其他失败情况返回错误号
介绍
pthread_cond_timedwait 函数允许线程等待一个指定的时间段
如果在这段时间内条件没有变为真,函数会返回
通知
单个通知
使用 pthread_cond_signal 函数唤醒一个等待条件变量的线程
pthread_cond_signal()
功能
唤醒一个等待条件变量的线程。
函数原型
int pthread_cond_signal(pthread_cond_t *cond);
参数
cond:要通知的条件变量的指针
返回值
成功时返回0
失败时返回错误号
广播通知
使用 pthread_cond_broadcast 函数唤醒所有等待条件变量的线程
pthread_cond_broadcast()
功能
唤醒所有等待条件变量的线程
函数原型
int pthread_cond_broadcast(pthread_cond_t *cond);
参数
cond:要通知的条件变量的指针
返回值
成功时返回0
失败时返回错误号
销毁
pthread_cond_destroy():
功能
销毁一个已初始化的条件变量
函数原型
int pthread_cond_destroy(pthread_cond_t *cond);
参数
cond:要销毁的条件变量的指针
返回值
成功时返回0
失败时返回错误号
注意
在调用 pthread_cond_wait 或 pthread_cond_timedwait 之前,线程必须持有与条件变量关联的互斥锁
当条件变量被通知并唤醒线程时,线程会自动重新获得互斥锁
为了避免虚假唤醒,通常在一个循环中检查条件,并在条件不满足时调用 pthread_cond_wait
信号量
简介
同步原语,用于控制多个线程对共享资源的访问
是一个整数值,通常用于表示可用资源的数量
提供了两个主要的操作:wait(或P操作)和signal(或V操作)
基本概念和操作
初始化
信号量可以被初始化为任何非负整数值,表示资源的初始数量
wait (P操作)
当线程想要获取一个资源时,它会执行wait操作
这会导致信号量的值减少1
如果信号量的值在操作前已经是0,那么执行wait操作的线程会被阻塞,直到其他线程释放资源
signal (V操作)
当线程释放一个资源时,它会执行signal操作
这会导致信号量的值增加1
如果有线程因为wait操作而被阻塞,那么一个线程会被唤醒
相关函数
sem_init()
函数原型
int sem_init(sem_t *sem, int pshared, unsigned int value);<br>
功能
初始化一个信号量
参数
sem指向要初始化的信号量的指针
pshared
如果设置为非零值,信号量将在进程之间共享
否则,它只能在同一进程的线程之间共享
value
信号量的初始值
sem_wait()
函数原型
int sem_wait(sem_t *sem);
功能
减少信号量的值
如果信号量的值为0,则调用线程会被阻塞
参数
sem:要操作的信号量的指针
sem_post()
函数原型
int sem_post(sem_t *sem);
功能
增加信号量的值,并唤醒任何等待的线程
参数
sem:要操作的信号量的指针
sem_destroy()
函数原型
int sem_destroy(sem_t *sem);
功能
销毁一个信号量,释放其相关的资源
参数
sem:要操作的信号量的指针
0 条评论
下一页