Linux 线程编程2.0——线程同步-互斥锁

当我们需要控制对共享资源的存取的时候,可以用一种简单的加锁的方法来控制。我们可以创建一个读/写程序,它们共用一个共享缓冲区,使用互斥锁来控制对缓冲区的存取。 

  函数 pthread_mutex_init()用来生成一个互斥锁。其函数原型如下:

#include<pthread.h>

int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);

第一个参数是互斥变量的地址,第二个参数设置互斥变量的属性,大多数情况下.选择默认属性,则传入空指针 NULL。

  Pthread_mutex_lock()函数声明开始用互斥锁上锁,此后的代码直至调用 pthread_mutex_ unlock()为止,均被上锁,即同一时间只能被一个线程调用执行。当一个线程执行到 pthread_mutex_lock()处时,如果该锁此时被另一个线程使用,那么此线程被阻塞,线程一直阻塞知道另一个线程释放此互斥锁。这两个函数原型是:

 int pthread_mutex_lock(pthread_mutex_t *mutex);

 int pthread_mutex_unlock(pthread_mutex_t *mutex);

  两个函数的参数都是互斥变量的地址。函数执行成功返回 0,否则返回错误号。

  互斥锁使用很方便,但是有一个缺点是使用互斥锁的过程中很有可能会出现死锁:两个线程试图同时占有两个资源,并按不同的次序锁定相应的互斥锁,例如两个线程都需要锁定互斥锁 l 和互斥锁 2,A 线程锁定了互斥锁 l,B 线程了锁定互斥锁 2,此时如果 A 线程在解除互斥锁 l 之前又去锁定互斥锁 2,而 B 恰好又需要去锁定互斥锁 l,这时就出现了死锁。看起来像是绕口令,通俗一点的来解释:线程 A 和线程 B 都需要独占使用 2 个资源,但是他们都分别先占据了一个资源,然后有相互等待另外一个资源的释放,这样的形成了一个死锁。此时我们可以使用函数 pthread_mutex_trylock(),它是函数 pthread_mutex_lock()的非阻塞函数,当它发现死锁不可避免时,它会通过 errno 返回 EBUSY,我们可以针对死锁做出相应的处理。Pthread_mutex_try_lock()的函数原型是:

int  pthread_mutex _trylock( pthread_mutex_t*mutex);

  当互斥锁不再使用的时候,应当释放互斥变量,函数 pthread _mutex.destory()用来释放一个互斥变量。

代码:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

char buffer[128];
int buffer_has_data=0;
pthread_mutex_t mutex;

void write_buffer (char *data)
{
    /* 锁定互斥锁*/
    pthread_mutex_lock (&mutex);
    if (buffer_has_data == 0)
    {
        sprintf( buffer, "%s", data);
        buffer_has_data=1;
    }
    /* 打开互斥锁*/
    pthread_mutex_unlock(&mutex);
}

void  read_buffer(void)
{
    while(1){
        /* 锁定互斥锁*/
        pthread_mutex_lock(&mutex);
        if(buffer_has_data == 1)
        {
            printf("Read buffer, data = [%s]\n", buffer);
            buffer_has_data=0;
        }
        /* 打开互斥锁*/
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
}

int main ( int argc, char **argv )
{
    char input[128];
    pthread_t reader;
    /* 用默认属性初始化一个互斥锁对象*/
    pthread_mutex_init( &mutex, NULL );
    pthread_create(&reader, NULL, (void *)(read_buffer), NULL);
    while( 1 )
    {
        scanf( "%s", input );
        write_buffer( input );
    }
    return 0;
}

原文地址:https://www.cnblogs.com/it8343/p/9240856.html

时间: 2024-10-27 14:09:32

Linux 线程编程2.0——线程同步-互斥锁的相关文章

编程之美--信号量与互斥锁选择(转)

编程之美--多线程高效下载的问题 2011-03-27 15:27:12 分类: C/C++ 基本的思路: 这个问题相当于是生产者和消费者模型的问题 首先定义两个线程,一个是下载线程,一个是存储线程,下载线程将数据从网络上下载到相应的数据的缓冲区中(BLOCK组成的队列).存储的线程从数据缓冲区中读取相应的数据,并将其写到相应的磁盘上去. 多线程同步的方式有:CriticalSection.Mutex和Semaphore(信号量).因为CriticalSection和Mutex,将不会使下载线程

Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信

目录 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 2.僵尸进程和孤儿进程 2.1僵尸进程 2.2孤儿进程 2.3僵尸进程如何解决? 3.互斥锁,锁 3.1互斥锁的应用 3.2Lock与join的区别 4.进程之间的通信 进程在内存级别是隔离的 4.1基于文件通信 (抢票系统) 4.2基于队列通信 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 1.创建进程的两种方式: 函数, 类. 2.pid: os.getpid() os.get

Linux线程同步---互斥锁

线程中互斥锁使用的步骤与信号量相似! 1.首先定义互斥锁变量,并初始化 pthread_mutex_t mutex_lock;pthread_mutex_init(&mutex_lock,NULL);2.在操作前对互斥量进行加锁操作 pthread_mutex_lock(&mutex_lock);3.操作完毕后进行解锁操作 pthread_mutex_unlock(&mutex_lock); 所有操作均在加锁和解锁操作之间进行,保证同时仅仅对有一个操作对关键变量或是区域进行操作.

Linux多线程(三)(同步互斥)

1. 线程的同步与互斥 1.1. 线程的互斥 在Posix Thread中定义了一套专门用于线程互斥的mutex函数.mutex是一种简单的加锁的方法来控制对共享资源的存取,这个互斥锁只有两种状态(上锁和解锁),可以把互斥锁看作某种意义上的全局变量.为什么需要加锁,就是因为多个线程共用进程的资源,要访问的是公共区间时(全局变量),当一个线程访问的时候,需要加上锁以防止另外的线程对它进行访问,实现资源的独占.在一个时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行操作.若其他线

python并发编程之多进程(二):互斥锁(同步锁)&amp;进程其他属性&amp;进程间通信(queue)&amp;生产者消费者模型

一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终端 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('

【黑马】程序员————多线程(二)单例设计模式、线程间通信,JDK1.5互斥锁

------Java培训.Android培训.iOS培训..Net培训.期待与您交流!----- 一.单例设计模式 单例设计模式的意义: A.保证类在内存中只有一个对象,不提供外部访问方式,构造函数用private修饰. B.提供公共方法(static修饰,类的静态方法),获取类的实例.单例设计模式分为饿汉和懒汉两种模式. 饿汉式&懒汉式 class Test33 { public static void main(String[] args) { Fanjianan.getInstance()

Linux组件封装(一)中互斥锁MutexLock的封装

本文对Linux中的pthread_mutex_t做一个简易的封装. 互斥锁主要用于互斥,互斥是一种竞争关系,主要是某一个系统资源或一段代码,一次做多被一个线程访问. 条件变量主要用于同步,用于协调线程之间的关系,是一种合作关系. Linux中互斥锁的用法很简单,最常用的是以下的几个函数: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); int pthread_mutex_

【转】Linux平台上用C++实现多线程互斥锁

原作者:chexlong 原文地址:http://blog.csdn.net/chexlong/article/details/7058283 在上篇用C++实现了Win32平台上的多线程互斥锁,这次写个Linux平台上的,同样参考了开源项目C++ Sockets的代码,在此对这些给开源项目做出贡献的斗士们表示感谢! 下边分别是互斥锁类和测试代码,已经在Fedora 13虚拟机上测试通过. Lock.h [cpp] view plaincopy #ifndef _Lock_H #define _

Linux系统编程——进程和线程的区别与联系

在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体. 为了让进程完成一定的工作,进程必须至少包含一个线程. 进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己的地址空间,有自己的堆,上级挂靠单位是操作系统.操作系统会以进程为单位,分配系统资源,所以我们也说,进程是资源分配的最小单位.更多详情,请看<进程的介绍>. 线程存在与进程当中,是操作系统调度执行的最小单位.