线程同步之互斥锁

因为一个进程中的各线程对共享资源都具有访问权限,就会产生竞争关系,所以需要互斥锁。

1、互斥锁的过程:

线程X加锁

线程X访问共享资源

线程A解锁

注意:互斥锁是建议锁,不具有强制性(即:不能阻止其他无锁的线程访问另一线程锁内的共享资源)

解释:如果线程A加锁,

线程B加锁,

线程C未加锁,

线程B需要等到线程A解锁,才能访问共享资源,但是线程C可以不等线程A解锁就直接成功访问共享资源,这样就造成了访问资源混乱。

因此:多个线程都要访问共享资源,在访问共享资源时,都要先加锁

2、互斥量

pthread_mutex_t mutex;

mutex只有0和1两个值。mutex初值为1,加锁成功mutex减1由1变为0,解锁成功mutext加1,由0变为1;

3、互斥量函数

1)pthread_mutex_init//对互斥量进行初始化

pthread_mutex_t mutex;
pthread_mutex_init(&mutex,NULL);

mutex==1

也可以使用:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER,这样就不需要pthread_mutex_destroy了。

2)pthread_mutex_destroy//销毁互斥量

pthread_mutex_detroy(&mutex);

与pthread_mutex_init()进行对应,需要对互斥量进行销毁。

3)pthread_mutex_lock//对互斥量进行加锁

mutex--

pthread_mutex_lock(&mutex);

4)pthread_mutex_unlock//对互斥量进行解锁

mutex++

pthread_mutex_unlock(&mutex);

5)pthread_mutex_trylock//尝试对互斥量进行加锁

如果未加锁,就加锁,如果已加锁,就返回一个异常值。

与pthread_mutex_lock的区别:pthread_mutex_lock时,如果锁未被释放,则线程阻塞等待;

pthread_mutex_trylock则如果锁未被释放,线程不阻塞等待,直接返回,需要轮询。

int ret = pthread_mutex_trylock(&mutex);
if(ret==0)
{
    //do sth.
    pthread_mutex_unlock(&mutex);
}else{
    //do sth.
}

4、应用实例

pthread_mutex_t mutex;
void* func(void *arg)
{
    srand(time(NULL));
    while(1)
    {
        pthread_mutex_lock(&mutex);
        printf("hello ");
        sleep(rand()%3);
        printf("world\n");
        //sleep(rand()%3);//放在解锁外边,要不主线程不容易抢到cpu
        pthread_mutex_unlock(&mutex);
        sleep(rand()%3);
    }
    return NULL;
}
int main(int argc, char *argv[])
{
    pthread_t thread;
    srand(time(NULL));
    pthread_mutex_init(&mutex,NULL); //子线程创建之前就初始化
    pthread_create(&thread,NULL,func,NULL);
    while(1)
    {
        pthread_mutex_lock(&mutex);
        printf("HELLO ");
        sleep(rand()%3);
        printf("WORLD\n");
        //sleep(rand()%3);//放在解锁外边,要不子线程不容易抢到cpu
        pthread_mutex_unlock(&mutex);
        sleep(rand()%3);
    }
    
    pthread_mutex_destroy(&mutex);
    

    
    return 0;
}

共享数据是 stdout,,即printf的打印输出//父线程和子线程都在向标准输出这一文件中写内容,故存在竞争,需要加互斥锁。

注意:访问共享资源前加锁,访问共享资源后立即解锁,锁的粒度应该越小越好,如上所示,

printf这个共享资源使用结束后,立即解锁,另外,sleep放在解锁里边的话,解锁后又继续执行while循环,另一个线程不容易获取cpu,以上两个原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值