qemu多线程技术的实现

本文深入探讨QEMU中的多线程技术,包括qemu_mutex的互斥锁属性、操作及实例,qemu_cond的条件变量、注意事项和应用,qemu_sem信号量的使用,以及qemu_thread的工作原理与线程属性函数。内容覆盖从基本的锁机制到复杂的线程同步,解析QEMU如何实现高效并发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 qemy_mutex_*

  qemu_mutex_init –> pthread_mutex_init、qemu_mutex_destroy –> pthread_mutex_destroy、qemu_mutex_lock –> pthread_mutex_lock(如果锁被占据,则阻塞当前线程)、qemu_mutex_trylock –> pthread_mutex_trylock(不会阻塞当前线程,会立即返回一个锁的状态值)、qemu_mutex_unlock –> pthread_mutex_unlock

1.1 互斥锁属性

  互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。
  当前(glibc2.2.3,linuxthreads0.9)有四个值可供选择:
    * PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
    * PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
    * PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。
    *PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。

1.2 锁操作

  主要包括加锁pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁 pthread_mutex_trylock()三个,不论哪种类型的锁,都不可能被两个不同的线程同时得到,而必须等待解锁。

1.3 实例代码
#include<stdio.h>
#include<pthread.h>
#include<string.h>
typedef struct{
        int count;
        pthread_mutex_t mutex;
}counter;
void reader(void *arg);
void writer(void *arg);
#define writer_c 10
#define reader_c 20
#define total_c writer_c + reader_c
int main(int argc, char *argv[]){
        counter C;
        C.count = 0;
        srand(time(NULL));
        pthread_mutex_init(&(C.mutex), NULL);
        pthread_t pt[total_c];
        int ret, i;
        for(i = 0; i < reader_c; i ++){
                ret = pthread_create(&pt[i], NULL, (void *)reader, (void *)&C);
                if(ret){
                        printf("reader %d create error!\n", i + 1);
                        return -1;
                }
        }
        for(i = 0; i < writer_c; i ++){
                ret = pthread_create(&pt[reader_c + i], NULL, (void *)writer, (void *)&C);
                if(ret){
                        printf("writer %d create error!\n", i + 1);
                        return -1;
                }
        }
        for(i = 0; i < total_c; i ++){
                pthread_join(pt[i], NULL);
        }
        return 0;
}
void reader(void *arg){
        counter *c = arg;
        while(1){
                pthread_mutex_lock(&(c->mutex));
                if(c->count > 0){
                        c->count --;
                        printf("reader-%lu: (c->count --) = %d\n", pthread_self(), c->count);
                }else{
                        printf("reader-%lu: get nothing!\n", pthread_self());
                }
                pthread_mutex_unlock(&(c->mutex));
                sleep(rand() % 10);
        }
}
void writer(void *arg){
        counter *c = arg;
        while(1){
                pthread_mutex_lock(&(c->mutex));
                c->count ++;
                printf("writer-%lu: (c->count ++)= %d\n", pthread_self(), c->count);
                pthread_mutex_unlock(&(c->mutex));
                sleep(rand() % 6);
        }
}
1.4 缺陷

  使用锁机制可以满足线程之间的互斥关系,但是还存在线程同步关系,比如:reader线程和writer线程之间存在同步关系,即:当writer线程产生一个资源(c->count ++)之后,reader线程便可以立即取走该资源(c->count –),因此可以立即唤醒一个被阻塞的reader线程,如果继续等待系统调度一个被阻塞的reader线程或者writer线程的话,便会造成效率低。条件变量是一种通过信号机制和锁机制来解决上述线程同步关系,大致的原理为&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值