zoukankan      html  css  js  c++  java
  • 线程(创建、终止、等待、分离、同步、互斥)

    进程在各自在自己的地址空间中运行,进程间通信要通过进程间通信机制实现,但是一个进程的地址空间中可以执行多个线程,这些线程除了共享数据段还共享文件描述符表,用户id组id,和当前工作目录,errno变量。但同一进程中的线程还有其所独有的:线程id、上下文(寄存器、程序计数器、栈指针)、调度优先级、等等。

    线程的创建函数:

    int pthread_create(pthread_t*thread,const pthread_att_t*attr,void*(*start_routine)(void*),void*arg);

    若成功返回0,错误返回错误号,当一个线程调用此函数继续往下执行,新的线程所执行的代码由函数指针start_routine决定,start_routine接受一个通过pthread_creat函数传进来的void*类型参数arg,start_routine返回时此线程结束。别的线程调用pthread_join得到start_routine的返回值。

    线程的终止:

    1、从线程函数返回(main函数除外)

    2、一个线程调用pthread_cancel终止同一进程中的另一线程

    3、线程调用pthread_exit(void *retval)终止自己

    线程的等待:

    int pthread_join(pthread_t thread,void **retval)

    调用该函数的线程将挂起等待,直到id为thread的线程终止

    查看线程不同终止方式返回,value_ptr所指向的内存的值:

    运行结果:

     线程的分离:

    线程终止后,线程状态一直保留到其他线程调用pthread_join获取状态为止,但线程也可以被置detach状态,这样一旦终止就立刻回收它所占有的资源,而不保留终止状态。

    分离函数:int pthread_detach(pthread_t thread);

    可结合的线程能被其它线程收回其资源和杀死,被其他线程回收之前,存储器资源不释放,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在终止时由系统自动释放。

     调用pthread_join后,如果线程没有运行结束,调用者会被阻塞,但有时当主线程创建多个子线程进行处理,并不像希望调用pthread_join阻塞,这时就可以置线程为分离状态,这样一来线程运行结束后会自动释放资源。

    运行结果:(证明分离的线程状态不能调用pthread_join函数)

    线程的同步:

    多线程的程序,访问冲突很普遍,可以引入互斥锁(Mutex),获得锁的线程可以进行读写修改操作,然后释放锁给其它线程。

    A:实现互斥锁的操作:

    lock:

          movb $0,%al

         xchgb %al,mutex

    if(al寄存器的内容>0){

          return 0;

    }else 

         挂起等待;

    goto lock;

    unlock:

        movb $1 ,mutex

        唤醒等待Mutex的线程;

    return 0;

    其中“挂起等待”和“唤醒等待线程”的实现:每个Mutex有一个等待队列,一个线程要在Mutex上挂起等待,首先要将自己加入到等待队列中,然后置线程为睡眠状态,然后调用调度器函数切换到别的线程,一个线程要唤醒等待队列中的其他线程,只需从等待队列中取出一项,将睡眠状态改为就绪,加入就绪队列。

    引起死锁的两种典型情况:

    如果所有线程在需要多个锁时都按相同的先后顺序(常见的是按Mutex变量的地址顺序)获得锁,则不会出现死锁。也可以使用pthread_mutex_trylock调用替代pthread_mutex_lock

     B:条件变量

    线程间的同步还有这样这种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条
    件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执

    C:Semaphore(信号量)

    信号量和Mutex类似,表示可用资源的数量,信号量的数量大于1。

    int sem_init(sem_t *sem,int pshared,unsigned int value);value:可用资源数量;pshared=0,表示同一进程的线程同步

    int sem_wait(sem_t *sem);semaphore减1,如果调用时已经为0,则挂起等待

    int sem_trywait(sem_t *sem);

    int sem_post(sem_t *sem);释放资源,semaphore加1

    int sem_destory(sem_t *sem);

    D:读写锁

    一个读写锁只能有一个写者或多个读者,但不能即有读者又有写者。

  • 相关阅读:
    Storm分布式实时流计算框架相关技术总结
    上手开源项目的几点建议【转】
    笔试面试的路上——努力ing
    Storm配置项详解【转】
    storm UI
    leetcode-单词探索
    leetcode-全排列详解(回溯算法)
    leetcode-生成括号(回溯算法)
    leetcode-递增的三元子序列
    leetcode-最长无重复字符的子串
  • 原文地址:https://www.cnblogs.com/Blog-day/p/My_Blog_Days1-26.html
Copyright © 2011-2022 走看看