河南周口东宇网站建设,微信公众号微信公众平台,除了凡科建站还有什么网站吗,搜狗营销线程锁的必要性比如一个多线程抢票程序#xff0c;tickets作为临界资源#xff0c;所有的线程都要对它进行判断ticket是否大于0#xff0c;以及ticket–的操作。用ticket–操作举例#xff0c;虽然他看起来是一行C语言的代码#xff0c;但是实际上它的底层汇编经历了三个阶…线程锁的必要性比如一个多线程抢票程序tickets作为临界资源所有的线程都要对它进行判断ticket是否大于0以及ticket–的操作。用ticket–操作举例虽然他看起来是一行C语言的代码但是实际上它的底层汇编经历了三个阶段分别是load命令减法命令以及store命令。由于线程是不断在切换的因此一个线程在执行完load命令之后很可能还没来得及做减法或者写回操作就被切走了。CPU开始执行下一个线程。所以就会出现tickets为负数的情况。锁的原理我们发现tickets是所有线程都可以看到的资源因此是临界资源。而锁也是所有线程都可以看到的资源那么为什么它不会造成线程安全问题呢这是因为加锁和解锁的过程是原子性的。它的关键在于:只使用一条汇编就将内存中的数据和CPU寄存器中的数据进行交换了。进程终止进程终止时系统不会自动释放所持有的互斥锁、读写锁和Posix信号量进程终止时内核总是自动清理的唯一同步锁类型是fcntl记录锁。System V信号量应用程序可以选择进程终止时内核是否自动清理某个信号量。要理解这一过程首先要理解上下文数据的概念。其实就是线程被切换后它的PCB中保存着执行的数据。当线程A到来时假设它要抢锁目前其他线程没有它来的快。它的寄存器al的数据现在是0执行交换操作将内存中mutex的值交换给A的寄存器al中此时线程A的al值为1内存中mutex的值为0。当线程A被切换走时(是带着上下文数据1一起被切走的)线程B到来它的al寄存器中的值为0(线程设置的是自己的上下文数据互相不冲突)进行交换mutex的值和al寄存器的值(0和0交换)最终B拿到的值是0发生挂起等待。此时就可以根据每个线程的al中寄存器的值判断是哪一个线程抢到了锁从而只允许该线程访问临时资源。当A访问完资源后释放锁唤醒等待的线程并将mutex的值置为1。注意拿到锁的A在访问临时资源的时候还是会被切换的只不过其他线程此时无法访问临时资源。站在其他线程的视角要么A没有申请锁不能访问临界资源要么A申请锁了访问了临界资源。因此线程A访问临界资源的动作具有原子性。线程终止(1)一个线程也可以在持有某个互斥锁期间终止自己调用pthread_exit或被另一个线程取消。如果线程调用pthread_exit资源终止时这时它应该知道自己还持有一个互斥锁(对于程序员来说)如果是被另一个线程取消的情况线程可以安装清楚处理程序(pthread_cleanup_push)在被取消时调用来释放相应的锁。(2)对于线程意外操作导致进程终止的情况就和进程终止时相同。