C/C++多线程与互斥锁

C/C++多线程与互斥锁

//获取线程ID:
//方法1、
void* thread(void *id){
        printf("this is a new thread, thread ID is %u\n", pthread_self());
        return NULL;
}

//方法2、
#include 
#include 
#define gettid() syscall(__NR_gettid)
//互斥锁:
pthread_mutex_t mutex;  //声明
pthread_mutex_init(&mutex, NULL); //初始化互斥锁
pthread_mutex_lock(&mutex); //加锁(返回0成功)
pthread_mutex_unlock(&mutex); //解锁(返回0成功)
pthread_mutex_destroy(&mutex); //释放资源
//条件锁:
pthread_mutex_lock(mutex);//加互斥锁
while(条件不成立)//当前线程中条件变量不成立
{
    pthread_cond_wait(cond, mutex);//解锁,其他线程使条件成立发送信号,加锁。
}
...//对进程之间的共享资源进行操作
pthread_mutex_unlock(mutex);//释放互斥锁

// 在另外一个线程中改变线程,条件满足发送信号。唤醒一个等待的线程(可能有多个线程处于阻塞状态),
// 唤醒哪个线程由具体的线程调度策略决定
pthread_cond_signal(pthread_cond_t * cond);
// 以广播形式唤醒所有因为该条件变量而阻塞的所有线程,唤醒哪个线程由具体的线程调度策略决定
pthread_cond_broadcast(pthread_cond_t * cond);
// 以阻塞方式等待,如果时间time到了条件还没有满足还是会结束
pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, struct timespec * time);

条件锁与互斥锁应用:
/* 对于线程一:
1.上锁
2.wait
3.解锁
*/
pthread_mutex_lock(&m_mutex);
pthread_cond_wait(&m_cond,&m_mutex);
//其他语句
pthread_mutex_unlock(&m_mutex);

/* 对于线程二:
1.上锁
2.signal
3.解锁
*/
pthread_mutex_lock(&m_mutex);
//其他语句
pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_mutex);
//自旋锁:
/*
前面的两种锁是比较常见的锁,也比较容易理解。下面通过比较互斥锁和自旋锁原理的不同,这对于真正理解自旋锁有很大帮助。
假设我们有一个两个处理器core1和core2计算机,现在在这台计算机上运行的程序中有两个线程:T1和T2分别在处理器core1和core2上运行,两个线程之间共享着一个资源。
首先我们说明互斥锁的工作原理,互斥锁是是一种sleep-waiting的锁。假设线程T1获取互斥锁并且正在core1上运行时,此时线程T2也想要获取互斥锁(pthread_mutex_lock),但是由于T1正在使用互斥锁使得T2被阻塞。当T2处于阻塞状态时,T2被放入到等待队列中去,处理器core2会去处理其他任务而不必一直等待(忙等)。也就是说处理器不会因为线程阻塞而空闲着,它去处理其他事务去了。
而自旋锁就不同了,自旋锁是一种busy-waiting的锁。也就是说,如果T1正在使用自旋锁,而T2也去申请这个自旋锁,此时T2肯定得不到这个自旋锁。与互斥锁相反的是,此时运行T2的处理器core2会一直不断地循环检查锁是否可用(自旋锁请求),直到获取到这个自旋锁为止。
从“自旋锁”的名字也可以看出来,如果一个线程想要获取一个被使用的自旋锁,那么它会一致占用CPU请求这个自旋锁使得CPU不能去做其他的事情,直到获取这个锁为止,这就是“自旋”的含义。
当发生阻塞时,互斥锁可以让CPU去处理其他的任务;而自旋锁让CPU一直不断循环请求获取这个锁。通过两个含义的对比可以我们知道“自旋锁”是比较耗费CPU的
头文件:#include  
自旋锁的类型:spinlock_t
*/
// 初始化
spin_lock_init(spinlock_t *x);
// 只有在获得锁的情况下才返回,否则一直“自旋”
spin_lock(x);
// 如立即获得锁则返回真,否则立即返回假
spin_trylock(x);
//释放锁
spin_unlock(x);
// 该宏用于判断自旋锁x是否已经被某执行单元保持(即被锁),如果是,返回真,否则返回假。
spin_is_locked(x);
//读写锁:
pthread_rwlock_t rwlock;
int data=1;
void readerA(){
    while(1){
        pthread_rwlock_rdlock(&rwlock);
        printf("A读者读出:%d\n",data);
        pthread_rwlock_unlock(&rwlock);
        Sleep(1000);
    }
}
void writerB(){
    while(1){
        pthread_rwlock_wrlock(&rwlock);
        data++;
        printf("B作者写入:%d\n",data);
        pthread_rwlock_unlock(&rwlock);
        Sleep(1000);
    }
}
int main()
{
    pthread_t t1;
    pthread_t t2;
    pthread_rwlock_init(&rwlock,NULL);
    pthread_create(&t1,NULL,readerA,NULL);
    pthread_create(&t2,NULL,writerB,NULL);
    pthread_join(t1,NULL);
    pthread_join(t2,NULL);
    pthread_rwlock_destroy(&rwlock);
    return 0;
}

C++多线程互斥锁:

#include 
#include 
#include 
int g_i = 0;
std::mutex g_i_mutex;  // 保护 g_i
void safe_increment()
{
    std::lock_guard<std::mutex> lock(g_i_mutex);
    ++g_i;
    std::cout << std::this_thread::get_id() << ": " << g_i << '\n';
    // g_i_mutex 在锁离开作用域时自动释放
}
int main()
{
    std::cout << "main: " << g_i << '\n';
    std::thread t1(safe_increment);
    std::thread t2(safe_increment);
    t1.join();
    t2.join();
    std::cout << "main: " << g_i << '\n';
}

你可能感兴趣的:(C/C++编程)