2018-2019-1 20165330 《信息安全系统设计基础》第八周学习总结

学习目标

  • 掌握三种并发的方式:进程、线程、I/O多路复用
  • 掌握线程控制及相关系统调用
  • 掌握线程同步互斥及相关系统调用

学习内容

基于进程的并发编程
  • 用进程构造并发程序
    • 服务器接收客户端的连接请求
      image
    • 服务器派生一个子进程为这个客户端服务
      image
    • 服务器接受另一个连接请求
      image
    • 服务器派生另一个子进程为新的客户端服务
      image
基于I/O多路复用的并发编程
  • I/O多路复用
    • 使用select函数,要求内核挂起进程,只有在一个或多个I/O事件发生后,才将控制返回给应用程序
    • select函数
       #include <sys/select.h>
       int select(int n,fd_set *fdset,NULL,NULL,NuLL);
       FD_ZERO(fd_set *fdset); /* Clear all bits in fdset */
       FD_CLR(int fd,fd_set *fdset); /* Clear bit fd in fdset */
       FD_SET(int fd,fd_set *fdset); /* Turn on bit fd in fdset */
       FD_ISSET(int fd,fd_set *fdset); /* Is bit fd in fdset on? */
                                                   处理描述符集合的宏
      
  • 并发事件驱动服务器
    • 每个输入事件都会引发一个从当前状态到下一状态的转移。
    • 服务器使用I/O多路复用,借助select函数检测输入事件的发生。当每个已连接描述符准备好可读时,服务器就为相应的状态机执行转移。
    • 对于每个新的客户端k,基于I/O多路复用的并发服务器会创建一个新的状态机Sk,并将它和已连接描述符dk联系起来。
      image
基于线程的并发编程
  • 创建线程

       #include <pthread.h>
       typedef void *(func)(void *);
       int pthread_create(pthread_t *tid,pthread_attr_t *attr,func *f,void *arg);
    
  • 初始化线程

       #include <pthread.h>
       pthread_once_t once_control = PTHREAD_ONCE_INIT;
       int pthread_once(pthread_once_t *once_control,void (*init_routine)(void));
    
  • 获取线程ID

        #include <pthread.h>
        pthread_t pthread_self(void);
    
  • 终止线程

    • 显示地终止
       #include <pthread.h>
       void pthread_exit(void *thread_return);
      
    • 以当前线程ID为参数调用pthread_cancel函数终止当前线程
       #include <pthread.h>
       int pthread_cancel(pthread_t tid);
      
  • 回收已终止的资源

       #include <pthread.h>
       int pthread_join(pthread_t tid,void **thread_return);
    
线程同步互斥
  • 信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作
    • P操作:如果s是非零的,那么P将减1,并且立即返回。如果s为零,那么就挂起这个线程,知道s变为非零,而一个V操作 会重启这个线程。在重启之后,P操作将s减1,并将控制返回给调用者
    • V操作:V操作将s加1。如果有任何线程阻塞在P操作等待s变成非零那么V操作会重启这些线程中的一个,然后该线程将s减1,完成它的P操作。
  • Linux下编译命令
    • gcc XXX.c -lpthread -o XXXX
    • gcc XXX.c -pthread -o XXXX
  • 线程互斥
    • 多个线程之间有共享资源时会出现互斥现象。
    • 当一个进程进入临界区使用临界资源时,另一个进程(线程)必须等待, 当占用临界资源的进程退出临界区后,另一进程才允许去访问此临界资源。
     #include <pthread.h>
     int pthread_mutex_destory(pthread_mutex_t *mutex);
     int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
     pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
  • 线程同步
    • 程相互等待
    • 当线程A使用某个对象,而此对象又需要线程B修改后才能符合本线程的需要,此时线程A就要等待线程B完成修改工作
     #include <pthread.h>
     int pthread_cond_destroy(pthread_cond_t *cond);
     int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
     pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    
  • 互斥锁
    • 获得锁的线程可以完成“读-修改-写”的操作,然后释放锁给其它线程
    • 没有获得锁的线程只能等待而不能访问共享数据
     #include <pthread.h>
      int pthread_mutex_lock(pthread_mutex_t *mutex);
      int pthread_mutex_trylock(pthread_mutex_t *mutex);
      pthread_mutex_t unlock(pthread_mutex_t *mutex);
    
  • 线程不安全函数类
    • 不保护共享变量的函数
    • 保持跨越多个调用的状态的函数
    • 返回指向静态变量指针的函数
    • 调用线程不安全函数的函数
  • 线程与进程
功能 进程 线程
创建 fork pthread_create
等待 wait/waitpid pthread_join
终止 exit/_exit pthread_exit
ID getpid/getppid pthread_self
互斥 semaphore mutex/semaphore
同步 semaphore cond var/semaphore
原文地址:https://www.cnblogs.com/besty-zyx/p/9974250.html