线程

使用线程的好处?

  • 异步变同步——在处理异步事件时,指定一个单独的线程(thread)去处理不同类型的事件,每个线程可以使用同步编程模型去处理它自己的事件,而同步模型要比异步简单很多。
  • 共享内存和文件描述符——在多进程情况下,操作系统必须提供复杂机制用来在进程间共享内存(memory)和文件描述符(file descriptors)。 而线程可以自动访问相同的内存地址空间和文件描述符
  • 任务分解,交叉执行——有些问题可以被分解,从而提高整个程序的吞吐量(throughput)。一个单线程的进程在处理多任务时,会隐式的将这些任务串行化,因为只有一个控制线程。而在多线程情况下,进程中相互独立的任务就可以每个都分配一个线程,从而实现交叉执行。
  • 缩短交互进程的响应时间——通过使用多线程,交互程序也可以缩短响应时间,多线程可以将程序中处理用户输入的部分和其他部分分开。

每个进程都含有表示执行环境所必须的信息,这些信息是

  • 进程ID(用于标识该线程属于哪个进程
  • 一组寄存器值(register value)
  • stack
  • 调度优先级和策略(scheduling priority and policy)
  • 信号屏蔽字(signal mask)
  • error变量
  • 线程特有数据(thread-specific data)

一个进程的所有信息对于该进程下的线程都是共享的这些信息是:

  • 执行程序的代码
  • 全局和堆内存
  • 文件描述符

 


二、线程标识 

  与进程ID在整个系统中是唯一的不同,线程只有在它所属的上下文中才有意义。

  线程的类型是pthread_t,实现时是用一个structure来代表pthread_t数据类型,所以呢?要比较两个线程的ID 就要采用函数。而且你是个结构体,很不方便打印线程值。

  使用下面这个函数比较两个线程是否相同:

#include <pthread.h>
    int pthread_equal(pthread_t tid1, pthread_t tid2);
        Returns: nonzero if equal, 0 otherwise     //相等返回非0值,否则返回0

 线程本身使用下面这个函数返回线程值:

#include <pthread.h>
  pthread_t pthread_self(void);
    Returns: the thread ID of the calling thread

   

在上面这个图中,主线程将job放在一个work queue中,主线程会在每个待处理job结构中放置处理该作用的线程ID,然后每个线程通过比较线程ID值来移出标有自己线程ID的job.


三、线程创建

  调用pthread_create函数创建线程:

  

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr,void *(*start_rtn)(void *), void *restrict arg);
      Returns: 0 if OK, error number on failure
  • tidp指向的内存是新创建的线程ID值
  • attr参数用于设置不同的线程参数,NULL代表线程具有默认属性
  • 新创建的线程从start_rtn函数的地址开始运行。

线程创建时并不能保证是哪个线程先会运行: 是新创建的线程还是调用线程。新创建的线程可以访问进程的地址空间,并且继承调用线程的浮点环境和信号屏蔽字(signal mask),然而该线程的挂起信号集会被清除。

陈小洁的三只猫
原文地址:https://www.cnblogs.com/ccpang/p/11402958.html