• linux网络编程学习笔记之四 -----多-threaded服务器


    对于使用过程中并发。通过实现更轻量级线程。

    每个线程都是一个独立的逻辑流。

    主题是CPU在执行调度的最小独立单位,这个过程是资源分配单元。当然,这是在微内核操作系统说。总之,这是唯一的一个操作系统内核提供了最重要的OS服务,许多人看点击打开链接


    每一个线程有它自己的线程上下文。包含一个唯一的线程ID(linux上实现为unsigned long),栈,栈指针。程序计数器、通用目的寄存器和条件码,还有自己的信号掩码和优先级。同一个进程里的线程共享这个进程的整个虚拟地址空间,包含可运行的程序文本、程序的全局内存、堆内存、栈和文件描写叙述符。因此,线程的上下文切换比进程迅速得多,但同一时候也带来了线程之间的同步问题。


    几个小Tips:

    1、进程ID在整个系统中是唯一的,但线程ID仅仅在它所属的线程环境里有效。

    2、每一个线程都有errno的副本,不用考虑其同步问题。

    3、随意一个线程调用了exit, _Exit, _exit都会造成整个进程的终止。

    4、因为描写叙述字的共享性,新创建线程并不影响已打开描写叙述字的引用计数。因此,不要随便close。


    线程的几个属性

    分离和可结合:假设一个线程能被其它线程收回其资源和杀死,它就是可结合的,否则就是分离的。默认情况下。线程被创建出来是可结合的。这时须要某个原有的线程调用pthread_join()来堵塞等待该进程结束并回收其资源(因为此函数仅仅能等待一个特定线程会导致编码复杂,Steven在UNP中可爱地吐槽了一段,当年与标准设计人员吵了一架)。

    而分离的线程无需其它线程等待,一旦结束。资源马上被操作系统回收,在其创建是调用pthread_detach()就可以实现。


    很多其它的属性如继承性。调度策略,调度 ,作用域和堆栈大小等能够參看APUE12.3

    对于属性变量pthread_attr_t能够调用pthread_attr_init设置,但要记得在创建线程后用pthread_attr_destory销毁



    进程同步常见方法

    1)相互排斥锁UNP26.7

    2)条件变量UNP26.8。须要注意的是pthread_cond_wait()假设没有信号。线程会堵塞直到有信号。但相互排斥量会马上释放。反之,它返回时,相互排斥量再次被锁住。

    3)信号量CSAPP12.5


    上面仅仅是简单地罗列和笔记。线程水太深。我将继续学习。

    惯例。上个简单的server端程序:

    #include"simon_socket.h"
    
    #define SERV_PORT 12345
    
    typedef struct arg_tag
    {
    	int connectfd;
    	struct sockaddr_in  addr_info;
    }ARG;
    
    
    void *start_routine(void *arg)
    { 
    	pthread_detach(pthread_self());
    
    	process_client(((ARG*)arg) -> connectfd, &((ARG*)arg) -> addr_info);
    	close(((ARG *)arg) -> connectfd);
    	
    	//free(arg);
    	pthread_exit(NULL);
    }
    
    int main()
    {
    	int sockfd, acfd;
    	size_t sin_len = sizeof(struct sockaddr);
    	ARG *arg;
    
    	struct sockaddr_in client_addr;
    
    	pthread_t thread;
    
    	sockfd = init_tcp_psock(SERV_PORT);
    	
    	while (1)
    	{
    		if ((acfd = accept_request(sockfd, (struct sockaddr *)&client_addr, &sin_len)) <= 0)
    			continue;
    
    		arg = malloc(sizeof(ARG));
    		arg -> connectfd = acfd;
    		arg -> addr_info = client_addr;
    
    		if (pthread_create(&thread, NULL, start_routine, (void*)arg))
    		{
    			printf("Create thread error!
    ");
    			continue;
    		}
    		free(arg);
    	}
    	close(sockfd);
    	return 0;
    }

    代码中一些调用函数的实现。移步我的github:https://github.com/simon-xia/lnp

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    redis sentinel(哨兵)配置解读
    配置哨兵监控Redis运行情况
    java 客户端链接不上redis解决方案
    Redis配置主从架构,实现读写分离
    Redis简介,安装和配置,停止,卸载(图解方式)
    linux下监控用户的操作记录---录像播放性质
    Spring的数据库开发
    Spring中Bean的作用域、生命周期
    Spring中Bean的实例化
    Spring之初体验
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4748814.html
Copyright © 2020-2023  润新知