zoukankan      html  css  js  c++  java
  • 29、深入理解计算机系统笔记,并发编程(concurrent)(1)

    1、如果逻辑控制流在时间上重叠,那么它们就是并发的。这种现象,称为并发(concurrency)。

    2、为了允许服务器同时为大量客户端服务,比较好的方法是:创建并发服务器,为每个客户端创建各自独立的逻辑流。现代OS提供的常用构造并发的方法有:

    进程和线程。

    1)每个逻辑流都是一个进程,由内核来调度维护。每个进程都有独立的虚拟地址空间,控制流通过IPC机制来进行通信。

    2)线程:运行在单一进程上下文中的逻辑流,由内核进行调度,共享同一进程的虚拟地址空间。

    由于进程控制和IPC的开销较高,所以基于进程的设计比基于线程的设计慢。

    常见IPC有:管道,FIFO,共享存储器,信号。

    3、基于线程的并发编程

    线程由内核自动调度,每个线程都有它自己的线程上下文(thread context),包括一个惟一的整数线程IDThread ID,TID),栈,栈指针,程序计数器,通用目的寄存器和条件码。每个线程和其他线程一起共享进程上下文的剩余部分,包括整个用户的虚拟地址空间,它是由只读文本(代码),读/写数据,堆以及所有的共享库代码和数据区域组成的,还有,线程也共享同样的打开文件的集合。

    1)线程执行模型

    wps_clip_image-20105

    wps_clip_image-24647

    wps_clip_image-16081

        线程不像进程那样,不是按照严格的父子层次来组织的。和一个进程相关的线程组成一个对等线程池(a pool of peers),独立于其他线程创建的线程(The threads associated with a process form a pool of peers, independent of which threads were created by which other threads.个人理解,这句是说独立于其他进程的线程池中的线程)。进程中第一个运行的线程称为主线程。对等(线程)池概念的主要影响是,一个线程可以杀死它的任何对等线程,或者等待它的任意对等线程终止;进一步来说,每个对等线程都能读写相同的共享数据。

    2)关于posix线程示例,及其相关函数,参见原书13.3.2节中。这部分举的例子很经典,值得一读

    3)分离线程

        在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,它的存储器资源(如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。

    示例程序

    /* 
     * echoservert.c - A concurrent echo server using threads
     */
    /* $begin echoservertmain */
    #include "csapp.h"
    
    void echo(int connfd);
    void *thread(void *vargp);
    
    int main(int argc, char **argv) 
    {
        int listenfd, *connfdp, port, clientlen=sizeof(struct sockaddr_in);
        struct sockaddr_in clientaddr;
        pthread_t tid; 
    
        if (argc != 2) {
    	fprintf(stderr, "usage: %s <port>\n", argv[0]);
    	exit(0);
        }
        port = atoi(argv[1]);
    
        listenfd = Open_listenfd(port);
        while (1) {
    	connfdp = Malloc(sizeof(int));
    	*connfdp = Accept(listenfd, (SA *) &clientaddr, &clientlen);
    	Pthread_create(&tid, NULL, thread, connfdp);
        }
    }
    
    /* thread routine */
    void *thread(void *vargp) 
    {  
        int connfd = *((int *)vargp);
        Pthread_detach(pthread_self()); 
        Free(vargp);
        echo(connfd);
        Close(connfd);
        return NULL;
    }
    /* $end echoservertmain */
    

  • 相关阅读:
    浅释一下,为什么要使用接口?
    枚举的简单使用
    最富有的人
    拜读websharp时,发现的几处问题(二)
    如何规划职业发展道路如何规划职业发展道路(ZT)
    在.NET环境中使用单元测试工具NUnit(ZT)
    [转贴]不得不知的几个可怕信息!
    ASP.NET中数据导入至Excel
    拜读websharp时,发现的几处问题(一)
    合并DataGrid相同单元格
  • 原文地址:https://www.cnblogs.com/mydomain/p/2102147.html
Copyright © 2011-2022 走看看