18.1 多线程服务器端的实现1 —— 线程概念
来源:互联网 发布:范剑青 知乎 编辑:程序博客网 时间:2024/05/17 06:25
1. Web服务器的发展迫使UNIX系列操作系统开始重视线程,Web服务器进程需要向多个客户端提供服务,因此逐渐舍弃进程,而用效率更高的线程。
2. 多进程模型的缺点:
a. 创建进程的过程需要大的开销;
b. 进程间通信需要用到IPC技术;
c. 经常发生“上下文切换Context Switching”,时间很长,很致命:进程A切换到进程B时,要将进程A信息移出内存,并读入进程B信息。
多线程(轻量级进程)的优点:
a. 线程的创建和上下文切换比进程更快;
b. 线程间通信无需特殊技术。
3. 进程VS线程
a. 每个进程都有自己的数据区、heap、stack,进程间相互独立。
线程间共享数据区和heap。
b. 进程:在操作系统构成单独执行流的单位;
线程:在进程构成单独执行流的单位;
4. 线程创建pthread_create
POSIX标准:Portable Operating System Interface for Computer Environment适用于计算机环境的可移植操作系统接口
#include <pthread.h>int pthread_create(pthread_t * restrict thread, const pthread_attr_t restrict attr, void *(*start_routine)(void *), void * restrict arg)成功返回0,失败其他值thread:保存新创建进程ID的变量地址值attr:用于传递线程属性的参数,NULL表示默认start_routine:线程的执行流函数指针arg:第三个参数函数指针的参数信息
5. 进程/线程等待pthread_join
int pthread_join(pthread_t thread, void **status)成功返回0,失败其他值thread:等待的线程IDstatus:保存线程的main函数返回值的指针变量地址值
6. 可在临界区critical section内调用的函数
临界区:多个线程同时调用函数时可能产生问题,这类函数内部存在临界区。临界区中至少存在一条这类代码。
线程安全函数:被多个线程同时调用时不会引发问题;线程安全函数的名称以_r后缀 //与临界区无关,安全函数也可能有临界区
非线程安全函数:被同时调用时会引发问题。
编译使用_r的函数方法:声明头文件前定义_REENTRANT,也可以# gcc -D_REENTRANT mythread.c -o mthread -lpthread
7. 示例:工作worker线程模型
代码只说模型应用,里面存在临界区问题。
#include <stdio.h>#include <pthread.h>void * thread_summation(void *arg);int sum = 0;int main(int argc, char *argv[]){pthread_t id_t1,id_t2;int range1[] = {1,5};int range2[] = {6,10};pthread_create(&id_t1,NULL,thread_summation,(void *)range1);pthread_create(&id_t2,NULL,thread_summation,(void *)range2);pthread_join(id_t1,NULL);pthread_join(id_t2,NULL);printf("sum = %d\n",sum);return 0;}void * thread_summation(void *arg){int start = ((int *)arg)[0];int end = ((int *)arg)[1];while(start <= end){sum += start;start++;}return NULL;}执行结果:
alex@alex-VirtualBox:~/Share/Test/tcpip$ gcc thread3.c -D_REENTRANT -lpthreadalex@alex-VirtualBox:~/Share/Test/tcpip$ ./a.outsum = 55
8. 临界区问题示例
#include <stdio.h>#include <pthread.h>#include <unistd.h>#include <stdlib.h>#define NUM_THREAD100void * thread_inc(void *arg);void * thread_des(void *arg);long long num = 0;//bit64int main(int argc, char *argv[]){pthread_t thread_id[NUM_THREAD];int i;for(i=0;i<NUM_THREAD;i++){if(i%2)pthread_create(&thread_id[i],NULL,thread_inc,NULL);elsepthread_create(&thread_id[i],NULL,thread_des,NULL);}for(i=0;i<NUM_THREAD;i++)pthread_join(thread_id[i],NULL);printf("result = %lld\n",num);return 0;}void * thread_inc(void *arg){int i;for(i=0;i<50000000;i++){num += 1;}return NULL;}void * thread_des(void *arg){int i;for(i=0;i<50000000;i++){num -= 1;}return NULL;}
执行结果:执行结果非0,而且每次执行结果都不一样!
alex@alex-VirtualBox:~/Share/Test/tcpip$ gcc thread4.c -D_REENTRANT -lpthreadalex@alex-VirtualBox:~/Share/Test/tcpip$ ./a.outresult = 4289148349alex@alex-VirtualBox:~/Share/Test/tcpip$ ./a.outresult = -4307619450
- 18.1 多线程服务器端的实现1 —— 线程概念
- 多线程 —— 线程组的概念,实现多个线程一起管理
- 实现服务器端的多线程SOCKET Server(独立监听线程)
- 【多线程-线程的概念】
- 多线程的聊天室实现-服务器端
- 多线程的聊天室实现-服务器端
- 多线程的聊天室实现-服务器端
- 线程概念,状态及状态之间的关系,实现多线程方法,实现同步线程的方式
- 多线程的概念、多线程的实现、线程的生命周期及状态
- 13.1 多线程的概念13.2 多线程实现13.3 线程的生命周期
- 多线程__【多线程的概念】【创建线程】【线程的状态】
- Java多线程回顾1:线程的概念及创建
- Linux C 网络编程——多线程的聊天室实现(服务器端)
- Linux C 网络编程——多线程的聊天室实现(服务器端)
- 转 Linux C 网络编程——多线程的聊天室实现(服务器端)
- Linux C 网络编程——多线程的聊天室实现(服务器端)
- Linux网络编程(四)——多线程实现简单的聊天(linux 服务器端 windows客户端)
- 服务器端的高性能实现(六)——状态机和线程池的引入
- Git学习笔记1
- 设计模式--2.策略模式
- Docker for zabbix
- canvas-视频绘制
- 快速pcb打样厂一般的Protel 99 SE转gerber文件步骤
- 18.1 多线程服务器端的实现1 —— 线程概念
- Sass的继承@extend
- NB-IoT终端开发流程
- ps梦幻效果技巧
- 控制反转和依赖注入
- Kurento模块开发指南之三:开发示例 Chroma Filter
- 数据算法
- 互联网新格局-敏捷转型三板斧大型讲座
- linux驱动编程——signal_pending