导航网站 win8风格,宽带技术网网站,wap网,wordpress数据库添加用户如果有十个银行账号通过不同的十条线程同时向同一个账号转账时#xff0c;如果没有很好的机制保证十个账号依次存入#xff0c;那么这些转账可能出问题。我们可以通过互斥量来解决。
C标准库提供了这个互斥量#xff0c;只需要引入threads.头文件。
互斥量就像是一把锁如果没有很好的机制保证十个账号依次存入那么这些转账可能出问题。我们可以通过互斥量来解决。
C标准库提供了这个互斥量只需要引入threads.头文件。
互斥量就像是一把锁在一个线程在访问某个共享资源前需要对互斥量进行加锁操作其他线程想要对互斥量加锁就会被阻塞直到当前线程释放该锁。当锁被释放后被阻塞的线程都开始继续执行并再次重复前面的步骤开始争夺可以对互斥量进行加锁的操作。
互斥量这种方式可以保证每次只有一个线程在操作共享资源。例子如下
#include threads.h
#include stdio.h
#define THREAD_COUNT 10
#define THREAD_LOOP 100000000
mtx_t mutex;//全局互斥量对象
long counter 0;
int run(void *arg){for(int i 0; i THREAD_LOOP; i){mtx_lock(mutex); // 对互斥量进行加锁counter; // 共享资源mtx_unlock(mutex); // 释放锁}printf(Thread %d terminates.\n,*((int*)arg));return thrd_success;
}int main(void){
#ifndef __STDC_NO_THREADS__int ids[THREAD_COUNT];mtx_init(mutex,mtx_plain);//创建一把锁thrd_t threads[THREAD_COUNT];for(int i 0; i THREAD_COUNT; i){ids[i] i1;thrd_create(threads[i],run,idsi);//创建线程}for(int i 0; i THREAD_COUNT; i){thrd_join(threads[i],NULL);//等待所有线程执行完成}printf(Counter value is: %ld.\n,counter);mtx_destroy(mutex);//销毁互斥量对象
#endifreturn 0;
}
~/Desktop$ gcc mtx.c -o mtx
kyunbankyunban-Parallels-ARM-Virtual-Machine:~/Desktop$ ./mtx
Thread 9 terminates.
Thread 5 terminates.
Thread 8 terminates.
Thread 1 terminates.
Thread 6 terminates.
Thread 7 terminates.
Thread 3 terminates.
Thread 2 terminates.
Thread 4 terminates.
Thread 10 terminates.
Counter value is: 1000000000.
在C语言中互斥量有三种
mtx_plain 最为简单的互斥量可对其进行基本的加锁和解锁操作但不适合需要重复加锁的场景如在递归调用中即使当前线程拥有该锁但对同一个mtx_plain互斥量重复加锁也会导致当前线程被阻塞从而导致死锁问题因为当前线程想要加锁就要先等待自己释放锁而要让当前线程释放锁就要先要它加锁成功完成对共享资源的操作后才能够释放锁如此一来就是一个无解的问题死锁就形成了对于递归调用中要用到锁的场景可以使用mtx_recursivemtx_recursive也被称为可重入互斥量它可以被同一个线程重复锁定多次而不会阻塞线程相应地要对它进行相应多次mtx_unlock才能够完全解锁。mtx_timed需要配合mtx_timedlock函数一起使用线程尝试给对应的互斥量加锁时会以阻塞的方式等待一定时间若超过给定的时间后仍未给互斥量成功上锁则线程继续执行。
C标准库还提供了以下两个与“互斥”有关的函数
call_once只调用指定方法一次即使它在多个线程中被调用。mtx_trylock锁住指定互斥量或直接返回