线程的基本概念、线程的基本状态及状态之间的关系?
http://blog.youkuaiyun.com/bornlili/article/details/55805732
线程是进程的一个顺序执行流。
线程是进程中的一个执行控制单元,执行路径。
一个进程中如果只有一个执行路径,这个程序称为单线程
一个进程中有多个执行路径时,这个程序成为多线程
新建态、就绪态、运行态、阻塞态、挂起态、结束态
线程与进程的区别
1、进程是系统分配资源的基本单位,线程是系统调度的基本单位
2、一个进程包含多个线程,一个线程必须隶属于一个进程,同一个进程中的线程共享资源:打开文件,地址空间,套接字,内核对象
3、线程间切换代价小,进程间切换代价大,
4、进程间通信没有线程间通信方便
5、进程有独立的地址空间,线程共用同一个地址空间
同步和互斥有何区别
同步,又称直接制约关系,是指多个线程(或进程)为了合作完成任务,必须严格按照规定的某种先后次序来运行。
互斥,又称间接制约关系,是指系统中的某些共享资源,一次只允许一个线程访问。当一个线程正在访问该临界资源时,其它线程必须等待。
同步包含互斥。
多线程同步和互斥有几种实现方法,都是什么?
互斥量
读写锁
临界区
信号量
条件变量
事件
哪些方法只能用于互斥?
关键段和互斥锁不能用于线程同步,因为它们都有线程所有权。
会记录当前线程的ID,并与尝试执行操作的线程ID进行比较。如果ID不相同则会拒绝执行。
关键段与互斥量的区别?
互斥量是内核对象,关键段是普通数据结构。
互斥量是内核对象,可以通过命名内核对象实现跨进程互斥。
关键段不是内核对象,其底层实现细节是一个数据结构,内含事件内核对象。所以关键段只能用于同一进程内的线程互斥。
由于互斥量是内核对象,每次使用都需要陷入内核态,开销大。
如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。
关键段如何使用,有何注意事项?
关键段包含四个函数:初始化,销毁,进入,离开
使用关键段前必须先执行初始化函数,所有线程结束关键段使用后需要执行销毁函数。
多次调用进入函数时,需要多次调用离开函数。
如果进入关键段失败,会使用一个事件内核对象把调用线程切换到等待状态。这意味着线程会切换到内核模式,开销非常大,在多处理器机器上,为了提高性能,可以配合旋转锁,尝试在一段时间内获得对资源的访问权,只有当尝试失败时才切换到内核模式进入等待状态。
读写锁使用注意事项
包含五个函数:初始化函数,获取读锁,释放读锁,获取写锁,释放写锁。没有销毁函数
与临界区不同,读锁不能递归地获得,一个线程不能为了多次写入资源而多次锁定资源。
条件变量和二元信号量的区别
信号量的递增和减少会被记录下来,不必担心会丢失。
而唤醒一个条件变量,如果没有相应的线程在等待该条件变量,这次唤醒将被丢失。
以下多线程对int型变量x的操作,哪个不需要进行同步()
A.++x 、B.x=y 、C.++ 、D.x=1
解析:
类似x++, x+=2, ++x这样的操作在多线程环境下是需要同步的。因为X86会按三条指令的形式来处理这种语句:从内存中读x的值到寄存器中,对寄存器加1,再把新值写回x所处的内存地址。
x=y 在X86上它包含两个操作:读取y至寄存器,再把该值写入x。
x=1 只需将1写入内存一条指令,属于原子操作,因此不需要同步。
一个全局变量tally,两个线程并发执行(代码段都是ThreadProc),问两个线程都结束后,tally取值范围。
inttally = 0;//glable
voidThreadProc()
{
for(inti = 1;i <= 50;i++)
tally += 1;
}
答:[50,100]