第18章 – 多线程服务器端的实现

这篇博客详细介绍了多线程服务器端的实现,包括线程的创建、销毁,互斥量和信号量的使用。讲解了pthread_create(), pthread_join(), pthread_mutex_init(), pthread_mutex_lock()等关键函数,并探讨了线程同步的重要性,以及在多线程并发服务器端实现中的应用,最后提到了简单的聊天程序实现。" 127761638,8709229,高低代码平台边界探索与融合实践,"['低代码开发', '业务建模', '开发工具', '企业应用', '融合平台']
摘要由CSDN通过智能技术生成

由于Web服务器端协议本身具有的特点,经常需要同时向多个客户端提供服务。因此,人们逐渐舍弃进程。

1、创建线程

函数 pthread_create()

#include <pthread.h>

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

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

功能:

​ 创建一个线程

参数:

​ thread:保存新创建线程ID的地址;

​ attr: NULL 表示创建一个线程;

​ start_routine 函数指针,在线程里运行的操作;

​ arg:函数指针的参数(地址值)。 传入的,可以在函数里用

返回值:

​ 成功,返回0;失败,返回其它值。

在这里插入图片描述

函数 pthread_join()

#include <pthread.h>

int pthread_join( pthread_t thread, void **status );

功能:

​ 调用该函数时,进程(或线程)会进入等待状态,直到第一个参数ID(thread)的线程终止为止(线程会销毁)。有了这个函数后就不用 sleep()让进程先睡眠, 等线程结束后再工作了(因为有时候无法预估线程的操作时间)。

​ 【问题】线程终止前,调用该函数的线程将进入阻塞状态。(所以用的更多的还是 pthread_detach()函数)

参数:

​ thread:该参数值ID的线程终止后才会从该函数返回;

​ status:创建线程 thread时,线程中进行的函数的返回值。(应为 void *型,用的时候自己要创建指针变量,然后记得 free() )

返回值:

​ 成功,返回0;失败,返回其它值。

在这里插入图片描述

2、互斥量

用于解决多线程同步问题。加锁就vans!

互斥量的创建与销毁

函数 pthread_mutex_init() 创建互斥量

#include <pthread.h>

int pthread_mutex_init( pthread_mutex_t * mutex, const pthread_mutexattr_t *attr);

功能:

​ 互斥量的创建。(不推荐使用宏的方法)

使用宏的方法:(要在全局变量的时候定义)

​ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

参数:

​ mutex:创建互斥量时传递保存互斥量的变量的地址值。(最好定义成全局变量);

​ attr:传递即将创建的互斥量属性,一般写 NULL。

返回值:

​ 成功,返回0; 失败,返回其它值。

函数 pthread_mutex_destroy() 销毁互斥量

#include <pthread.h>

int pthread_mutex_destroy( pthread_mutex_t *mutex );

功能:

​ 销毁互斥量

参数:

mutex:创建互斥量时传递保存互斥量的变量的地址值。(最好定义成全局变量);

返回值:

成功,返回0; 失败,返回其它值。

加锁、解锁

函数 pthread_mutex_lock() 加锁

#include <pthread.h>

int pthread_mutex_lock( pthread_mutex_t *mutex );

功能:

​ 上锁

参数:

mutex:创建互斥量时传递保存互斥量的变量的地址值。(最好定义成全局变量);

返回值:

成功,返回0; 失败,返回其它值。

函数 pthread_mutex_unlock() 加锁

#include <pthread.h>

int pthread_mutex_unlock( pthread_mutex_t *mutex );

功能:

​ 解锁;

参数:

mutex:创建互斥量时传递保存互斥量的变量的地址值。(最好定义成全局变量);

返回值:

成功,返回0; 失败,返回其它值。

3、信号量

信号量的创建 与 销毁

函数 sem_init(); 创建信号量

#include <semaphore.h>

int sem_init( sem_t *sem, int pshared, unsigned int value );

功能:

​ 创建信号量;

参数:

​ sem:创建信号量时传递保存信号量的变量地址值;

​ pshared:一般写 0;

​ value:指定新创建的信号量初始值。

返回值:

成功,返回0; 失败,返回其它值。

函数 sem_destroy(); 销毁信号量

#include <semaphore.h>

int sem_destroy( sem_t *sem );

功能:

​ 销毁信号量;

参数:

​ sem:销毁信号量时传递保存信号量的变量地址值;

返回值:

成功,返回0; 失败,返回其它值。

信号量的 增、减

函数 sem_post() 信号量增

#include <semaphore.h>

int sem_post( sem_t *sem );

功能:

​ 信号量 增;

参数:

sem:传递保存信号量读取值得地址, sem_post()时信号量增1,sem_wait()时信号量减1;

返回值:

​ 成功,返回0;失败,返回其它值。

函数 sem_wait () 信号量减

#include <semaphore.h>

int sem_wait ( sem_t *sem );

功能:

​ 信号量 减;

参数:

sem:传递保存信号量读取值得地址,sem_post()时信号量增1,sem_wait()时信号量减1;

返回值:

​ 成功,返回0;失败,返回其它值。

4、线程得销毁和多线程并发服务器端的实现

函数 pthread_detach() 销毁线程

#include <pthread.h>

int pthread_detach( pthread_t thread );

功能:

​ 销毁线程。

​ 之前调用过pthread _join()函数。调用该函数时,不仅会等待线程终止,还会引导线程销毁。但该函数的问题是,线程终止前,调用该函数的线程将进人阻塞状态。

因此,通常通过pthread_detach()函数调用引导线程销毁。

参数:

​ thread:终止的同时需要销毁的线程 ID;

返回值:

​ 成功,返回0;失败,返回其它值。

5、多线程并发服务器端实现 简单的聊天程序

【补】 函数 sprint()

由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。

//把整数123 打印成一个字符串保存在s 中。

sprintf(s, “%d”, 123); //产生"123"

// 打印123的字符串,并将 [123] 保存在 name变量中。

sprint(name, “[%s]”, “123”)

6、课后习题

1)单CPU系统中如何同时执行多个进程?请解释该过程中发生的上下文切换

答:因为系统将CPU切分成多个微小的块后分配给多个进程,为了分时使用CPU,需要”上下文切换“过程。”上下文切换“是指,在CPU改变运行对象的过程中农,执行准备的过程将之前执行的进程数据从换出内存,并将待执行额进程数据传到内存的工作区域

2)为何线程的上下文切换速度相对更快?线程间数据交换为何不需要类似IPC的特别技术?

答:因为线程进行上下文切换时不需要切换数据区和堆区。同时,可以利用数据区和堆区进行数据交换

3)请从执行流角度说明进程和线程的区别

进程:在操作系统中构成单独执行流的单位

线程:在进程内构成单独执行流的单位

4)bcd

5)d

6)请说明完全销毁Linux线程的两种方法

答:pthread_join函数和pthread_detach函数。

代码入口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值