精华内容
下载资源
问答
  • 多线程变量同步机制

    千次阅读 2017-02-27 10:20:51
    多线程中同一个变量会共享,但是有时候会发现不同线程中的共享变量,值不同步,原来每个线程都会有自己的内存存放变量的缓存值,而不是一起使用主内存中的变量值。 问题:主线程的while循环中,当flag为true时,循环...
    多线程中同一个变量会共享,但是有时候会发现不同线程中的共享变量,值不同步,原来每个线程都会有自己的内存存放变量的缓存值,而不是一起使用主内存中的变量值。
    
    
    问题:主线程的while循环中,当flag为true时,循环体为空的话,后面的打印语句不会执行,会一直在while里循环;
    而在循环体中加上一句语句,比如System.out.println(),循环就会正常结束,执行后面的输出语句。
    为什么当while循环体为空时不会退出循环,加入一句打印就会退出循环?
    
    
    例如:
     public class Test{
        public static void main(String args[]){
            R r=new R();
            Thread t=new Thread(r);
            t.start();
            while(!r.flag){
            }
            System.out.println("end");
        }
    }
    
    class R implements Runnable{
        public boolean flag=false;
        public void run(){
         int x=0;
            while(x<1000){
                x++;
                System.out.println(x);
            }
            flag=true;
        }
    
    }
    
    
    答:因为多线程之间不是绝对同步的。 
    在运行时为了提高效率会将数据加载到寄存器中,所以有时虽然内存中数据已经改变,但还未即时更新到寄存器中,就会出现不同步的情况。
    R 线程的 flag 是从其工作内存取,主线程的 while循环里什么都不写,会导致 调用访问 flag 太频繁,导致主内存不会 及时 刷新工作内存的 flag ,所以一直会访问到 flag false ,当加入 System.out.println() 后,jvm的调度机制(会选择在执行其他任务的时候同步flag)(访问flag有了明显间隔),所以当加了一句打印语句之后, 主内存就有空去刷新到 R 线程的工作内存,发现 flag 更新了,这样才能正常退出 while 循环。

    volatile 关键字可以强制每次都从主内存中读取,而不是用自己线程工作内存中的缓存,这样可以实现同步变量,但效率会低不少。
    例如:
    volatile  boolean  flag =false;

    展开全文
  • 多线程共享同一个进程的地址空间 优点:线程间较容易实现通信,通过全局变量实现数据共享和交换, 缺点:多个线程同时访问共享资源容易出现资源竞争,所以要引入同步和互斥机制。线程间同步:无名信号量,互斥锁...

    多线程共享同一个进程的地址空间
    优点:线程间较容易实现通信,通过全局变量实现数据共享和交换,
    缺点:多个线程同时访问共享资源容易出现资源竞争,所以要引入同步和互斥机制。

    线程间同步:无名信号量,互斥锁,事件,临界区;(后两个用的较少)
    无名信号量:实现同步的机制步骤
    (1)定义全局变量sem_t sem1,sem2;
    (2)在进程中初始化信号量:int sem_init(sem_t *sem,int pshared,int value);
    (3)进行P操作:int sem_wait(sem_t * sem);//信号量减一
    (4)进行V操作:int sem_post(sem_t * sem);//信号量加一
    注意:在这里可以使用一个信号量实现互斥锁;
    互斥锁: 实现同步机制的步骤
    (1)定义全局变量 pthread_mutex_t mutex;
    (2) 初始化互斥锁 int pthread_mutex_init(pthread_mutex_t * mutex,pthread_mutexattr_t *attr);
    函数参数 mutex :互斥锁
    attr : 互斥锁属性 //NULL表示缺省属性
    (3) 申请互斥锁 int pthread_mutex_lock(pthread_mutex_t * mutex);
    函数参数 mutex
    函数返回值 成功 0,出错 -1
    (4) 释放互斥锁 int pthread_mutex_unlock(pthread_mutex_t * mutex);
    函数参数 mutex
    函数返回值 成功 0,出错 -1
    无名信号量和互斥锁的实例可以访问这篇博客
    http://blog.csdn.net/xld_hung/article/details/75212332
    事件:事件机制,则允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。

    临界区:当多个线程访问一个独占性共享资源时,可以使用临界区对象。
    拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,
    则被挂起,直到拥有临界区的线程放弃临界区为止
    更多关于事件和临界区的知识可以访问下面这篇博客
    http://blog.csdn.net/minglingji/article/details/7488652

    展开全文
  • 多线程同步机制

    千次阅读 2017-09-08 23:36:17
    为什么要引入同步机制多线程环境中,可能会出现两个甚至更多的线程试图同时访问同一个资源。必须对这种潜在的资源冲突进行预防。解决方法在线程使用一个资源时为其加入锁机制。访问资源的第一个线程对其加上锁之后...

    为什么要引入同步机制

    在多线程环境中,可能会出现两个甚至更多的线程试图同时访问同一个资源。必须对这种潜在的资源冲突进行预防。

    解决方法

    在线程使用一个资源时为其加入锁机制。访问资源的第一个线程对其加上锁之后,其他线程便不能再使用那个资源,除非被解锁。

    例子

    比如银行取钱的例子:
    首先有一个银行账户:

    /**
     * 银行账户类,里面的余额为1000
     */
    class Bank {
        private int balance = 1000;
        /**
         * 取钱的方法
         * @param number 取钱的金额
         * @return
         */
        public  int getMoney(int number) {
            if (number < 0) {
                return -1;
            } else if (number > balance) {
                return -2;
            } else if (balance < 0) {
                return -3;
            } else {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                balance -= number;
                System.out.println("balance is:" + balance);
                return number;
            }
        }
    }

    取钱,可以可以通过柜台取钱,可以通过ATM取钱

    /**
     * ATM取钱
     */
    class AtmFetchMoney extends Thread {
        private Bank bank;
        public AtmFetchMoney(Bank bank) {
            this.bank = bank;
        }
        @Override
        public void run() {
            System.out.println("ATM取钱:" + bank.getMoney(800));
        }
    }
    
    /**
     * 柜台取钱
     */
    class GuiTaiFetchMoney extends Thread {
        private Bank bank;
        public GuiTaiFetchMoney(Bank bank) {
            this.bank = bank;
        }
        @Override
        public void run() {
            System.out.println("柜台取钱:" + bank.getMoney(800));
        }
    }

    现在开始模拟ATM和柜台同时在一起账户进行取钱的过程:

    public class FetchMoney {
        public static void main(String[] args) {
            /**
             * 模拟取钱过程,两个线程同时对一个账户进行操作。
             */
            Bank bank = new Bank();
            Thread t1 = new AtmFetchMoney(bank);
            Thread t2 = new GuiTaiFetchMoney(bank);
            t1.start();
            t2.start();
        }
    }

    结果1:

    balance is:-600
    balance is:-600
    柜台取钱:800
    ATM取钱:800

    -600 -600 第一个线程进来之后减去800之后,没有执行输出余额,那么第二个也减去了800,所以最后分别输出就是-600 -600
    结果2:

    balance is:200
    balance is:200
    ATM取钱:800
    柜台取钱:800

    200 200第一个线程进来之后800之后,没有减去余额,那么第二个线程进来之后拿到余额1000-800=200,所以最后分别输出就是200 200
    结果3:

    balance is:200
    ATM取钱:800
    balance is:-600
    柜台取钱:800

    200 -600第一个线程进来之后没有减去800,输出余额200,那么第二个线程进来之后拿到余额200-800=-600,最后输出的是200 -600
    通过上面的例子发现,多线程中如果对同一个资源进行操作会出现资源竞争的情况,该如何解决呢?

    引入同步机制synchronized

    由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问,利用synchronized关键字。

    改造上面的例子:

    在方法前面加上synchronized关键字

       public synchronized  int getMoney(int number) {
            //对方法加上synchronized关键字
            if (number < 0) {
                return -1;
            } else if (number > balance) {
                return -2;
            } else if (balance < 0) {
                return -3;
            } else {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                balance -= number;
                System.out.println("balance is:" + balance);
                return number;
            }
        }

    输出结果:

    balance is:200
    ATM取钱:800
    柜台取钱:-2

    可以看到ATM取钱之后,余额只剩下200,柜台再去取钱的时候就返回-2,表示余额不足,不会出现了余额不正确的情况。

    synchronized需要明确的几个问题:

    1.synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果 再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
    2.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
    3.每个对象只有一个锁(lock)与之相关联。
    4.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

    synchronized作用域:

    1。某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线 程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的 synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
    2。某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。

    展开全文
  • 进程通信方式 文件映射:本地之间 共享内存:本地之间 匿名管道:本地之间 命名管道:跨服务器 邮件槽:一对的传输数据,通常通过网络向一台Windows机器传输 剪切板:本地之间 socket:跨服务器 ...

    多进程通信方式

    1. 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
    2. 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
    3. 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
    4. 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
    5. 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
    6. 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
    7. 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

    个人对进程与线程的同步、通信的理解:
    同步 (互斥) 是为了多个进程完成同一个任务(使用同一块资源)而进行相互适应的操作,这期间可能涉及到通信;
    通信是进程间信息的交换,可能某些交换方式需要在实现同步(互斥)的前提下才能完成。

    以下转自https://www.cnblogs.com/youngforever/p/3250270.html

    这两天看进程的同步与通信,看了几本书上的介绍,也从网上搜了很多资料,越看越迷惑,被这几个问题搞得很纠结。

    1. 进程同步与互斥的区别?
    2. 进程的同步方式有哪些?
    3. 进程的通信方式有哪些?
    4. 进程同步与通信的区别是什么?
    5. 线程的同步/通信与进程的同步/通信有区别吗?

    在好多教材上(包括国内与国外的)也没有明确这些概念,现在对每个问题还没有准确的答案,下面将自己的理解记下来,以后再补充。

    参考资料:

    《操作系统教程》 孙钟秀主编 费翔林  骆斌  谢立参编 高等教育出版社

    《计算机操作系统》 何炎祥 李飞 李宁 编著 清华大学出版社(进程管理部分与《操作系统教程》中的类似)

    进程互斥、同步的概念

    进程互斥、同步的概念是并发进程下存在的概念,有了并发进程,就产生了资源的竞争与协作,从而就要通过进程的互斥、同步、通信来解决资源的竞争与协作问题。

    下面是根据《操作系统教程》3.1.4 中的介绍,整理的进程互斥、同步的概念。

    在多道程序设计系统中,同一时刻可能有许多进程,这些进程之间存在两种基本关系:竞争关系和协作关系。

    进程的互斥、同步、通信都是基于这两种基本关系而存在的,为了解决进程间竞争关系(间接制约关系)而引入进程互斥;为了解决进程间松散的协作关系( 直接制约关系)而引入进程同步;为了解决进程间紧密的协作关系而引入进程通信。

    第一种是竞争关系 

    系统中的多个进程之间彼此无关,它们并不知道其他进程的存在,并且也不受其他进程执行的影响。例如,批处理系统中建立的多个用户进程, 分时系统中建立的多个终端进程。由于这些进程共用了一套计算机系统资源,因而, 必然要出现多个进程竞争资源的问题。当多个进程竞争共享硬设备、存储器、处理器 和文件等资源时,操作系统必须协调好进程对资源的争用。

    资源竞争出现了两个控制问题:一个是死锁 (deadlock )问题,一组进程如果都获得了部分资源,还想要得到其他进程所占有的资源,最终所有的进程将陷入死锁。另一个是饥饿(starvation )问题,这是指这样一种情况:一个进程由于其他进程总是优先于它而被无限期拖延。

    操作系统需要保证诸进程能互斥地访问临界资源,既要解决饥饿问题,又要解决死锁问题。 
        进程的互斥(mutual exclusion )是解决进程间竞争关系( 间接制约关系) 的手段。 进程互斥指若干个进程要使用同一共享资源时,任何时刻最多允许一个进程去使用,其他要使用该资源的进程必须等待,直到占有资源的进程释放该资源。

    第二种是协作关系          

    某些进程为完成同一任务需要分工协作,由于合作的每一个进程都是独立地以不可预知的速度推进,这就需要相互协作的进程在某些协调点上协 调各自的工作。当合作进程中的一个到达协调点后,在尚未得到其伙伴进程发来的消息或信号之前应阻塞自己,直到其他合作进程发来协调信号或消息后方被唤醒并继续执行。这种协作进程之间相互等待对方消息或信号的协调关系称为进程同步。

    进程间的协作可以是双方不知道对方名字的间接协作,例如,通过共享访问一个缓冲区进行松散式协作;也可以是双方知道对方名字,直接通过通信机制进行紧密协作。允许进程协同工作有利于共享信息、有利于加快计算速度、有利于实现模块化程序设计。

    进程的同步(Synchronization)是解决进程间协作关系( 直接制约关系) 的手段。进程同步指两个以上进程基于某个条件来协调它们的活动。一个进程的执行依赖于另一
    个协作进程的消息或信号,当一个进程没有得到来自于另一个进程的消息或信号时则需等待,直到消息或信号到达才被唤醒。

    不难看出,进程互斥关系是一种特殊的进程同步关系,即逐次使用互斥共享资源,也是对进程使用资源次序上的一种协调。

    进程通信的概念

    下面是根据《操作系统教程》3.5 中的介绍,整理的进程通信的概念。

    并发进程之间的交互必须满足两个基本要求:同步和通信。

    进程竞争资源时要实施互斥,互斥是一种特殊的同步,实质上需要解决好进程同步问题,进程同步是一种进程通信,通过修改信号量,进程之间可建立起联系,相互协调运行和协同工作。但是信号量与PV操作只能传递信号,没有传递数据的能力。有些情况下进程之间交换的信息量虽很少,例如,仅仅交换某个状态信息,但很多情况下进程之间需要交换大批数据,例如,传送一批信息或整个文件,这可以通过一种新的通信机制来完成,进程之间互相交换信息的工作称之为进程通信IPC (InterProcess Communication)(主要是指大量数据的交换)。进程间通信的方式很多,包括: 

    1. 信号(signal )通信机制;
    2. 信号量及其原语操作(PV、读写锁、管程)控制的共享存储区(shared memory )通信机制;
    3. 管道(pipeline)提供的共享文件(shared file)通信机制;
    4. 信箱和发信/ 收信原语的消息传递(message passing )通信机制。
      其中前两种通信方式由于交换的信息量少且效率低下,故称为低级通信机制,相应地可把发信号/ 收信号及PV之类操作称为低级通信原语,仅适用于集中式操作系统。消息传递机制属于高级通信机制,共享文件通信机制是消息传递机制的变种,这两种通信机制,既适用于集中式操作系统,又适用于分布式操作系统。

    进程同步的方法

    前面提到,进程互斥关系是一种特殊的进程同步关系,下面给出常见的进程同步的方法,实际上也可用于进程的互斥(个人理解)。

    在何炎祥的《计算机操作系统》 3.2 节,将进程同步的机制与解决进程互斥方法看做是一样的,的明确指出互斥的软件解决方法为Dekker算法与Peterson算法,互斥的硬件解决方法为中断方法、以及使用机器指令的方法,后面又给出了信号量、管程、消息传递三种方法。

    实际应用中,不同的系统有不同的进程同步方法,CSDN帖子http://bbs.csdn.net/topics/80156687中有一些讨论,Linux 与Windows的主要同步、通信机制如下:

    Linux 下:

    Linux 下常见的进程同步方法有:SysVIPC 的 sem(信号量)、file locking / record locking(通过 fcntl 设定的文件锁、记录锁)、futex(基于共享内存的快速用户态互斥锁)。针对线程(pthread)的还有 pthread_mutex 和 pthread_cond(条件变量)。
     
    Linux 下常见的进程通信的方法有 :pipe(管道),FIFO(命名管道),socket(套接字),SysVIPC 的 shm(共享内存)、msg queue(消息队列),mmap(文件映射)。以前还有 STREAM,不过现在比较少见了(好像)。

    Windows下:
    在Windwos中,进程同步主要有以下几种:互斥量、信号量、事件、可等计时器等几种技术。

    在Windows下,进程通信主要有以下几种:内存映射、管道、消息等,但是内存映射是最基础的,因为,其他的进程通信手段在内部都是考内存映射来完成的。

    线程的同步/通信与进程的同步/通信有区别吗?

    对于该问题,教材上没有明确的回答,教材上给出的一般是进程而非线程的同步、通信方式。但网络上很多说法将两者混为一谈。根据教材,以及网上的说法,个人的理解为:

    同步机制:

    信号量、管程、互斥是进程的同步机制,而信号量、互斥也可用于线程的同步,但管程只在进程同步中被用到;

    线程的同步除了信号量、互斥外,还有临界区、事件,没有看到教材上将这两种方式作为进程的同步方式;

    通信机制:

    管道、FIFO、消息队列、信号量、共享内存是进程的同步机制,教材上没有线程的通信机制这样的说法,但可以肯定这几种方法是进程的通信方式,且其中的信号量既可用于进程的同步,又可用于进程的通信,在网络上还有说可以用于线程同步的。

    管道与管程是不同的,管程是进程同步的方式,而管道则是进程通信的方式。

    进程的同步/通信

    下面是常见的线程之间的同步方式的详细介绍。

    (注:下面转自网络,下面的同步、通信方式对于进程与线程分的不是很清楚,关于进程还是线程的解释见上面——线程的同步/通信与进程的同步/通信有区别吗?)

    一、进程/线程间同步机制。

    临界区、互斥区、事件、信号量四种方式
    临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别
    1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。

    在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
    2、互斥量:采用互斥对象机制。

    只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享 .互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。
    3、信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目 .

    信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。

    PV操作及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用共享资源的进程数。
       P操作申请资源:
      (1)S减1;
      (2)若S减1后仍大于等于零,则进程继续执行;
      (3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转入进程调度。
      
      V操作 释放资源:
      (1)S加1;
      (2)若相加结果大于零,则进程继续执行;
      (3)若相加结果小于等于零,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转入进程调度。
    4、事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作 .

    总结:
      1. 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。
      2. 互斥量(Mutex),信号灯(Semaphore),事件(Event)都可以被跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。所以可以使用WaitForSingleObject来等待进程和线程退出。
      3. 通过互斥量可以指定资源被独占的方式使用,但如果有下面一种情况通过互斥量就无法处理,比如现在一位用户购买了一份三个并发访问许可的数据库系统,可以根据用户购买的访问许可数量来决定有多少个线程/进程能同时进行数据库操作,这时候如果利用互斥量就没有办法完成这个要求,信号灯对象可以说是一种资源计数器。

    二、进程间通信方式

    由于比较容易混淆,我们把进程间通信方法也列在这里做比较。

    进程通信也就是所谓的IPC问题,主要是指进程间交换数据的方式。进程通信包括高级通信与低级通信,其中进程同步与互斥属于低级通信,主要用于插U农地控制信号;高级通信包括三种:共享存储系统(有的地方称作共享内存区)、消息传递系统(有的地方称作消息队列)、管道。

    信号量是进程同步与互斥的常用方法,也可以作为低级的进程通信方法,用于传递控制信号。

    简而言之,进程间通信方式主要包括管道、FIFO、消息队列、信号量、共享内存。 

    1.管道,还有命名管道和非命名管道(即匿名管道)之分,非命名管道(即匿名管道)只能用于父子进程通讯,命名管道可用于非父子进程,命名管道就是FIFO,管道是先进先出的通讯方式    

    2.消息队列,是用于两个进程之间的通讯,首先在一个进程中创建一个消息队列,然后再往消息队列中写数据,而另一个进程则从那个消息队列中取数据。需要注意的是,消息队列是用创建文件的方式建立的,如果一个进程向某个消息队列中写入了数据之后,另一个进程并没有取出数据,即使向消息队列中写数据的进程已经结束,保存在消息队列中的数据并没有消失,也就是说下次再从这个消息队列读数据的时候,就是上次的数据!!!!    

    3.信号量,它与WINDOWS下的信号量是一样的,所以就不用多说了    

    4.共享内存,类似于WINDOWS下的DLL中的共享变量,但LINUX下的共享内存区不需要像DLL这样的东西,只要首先创建一个共享内存区,其它进程按照一定的步骤就能访问到这个共享内存区中的数据,当然可读可写      

    以上几种方式的比较:    

    1.管道:速度慢,容量有限,只有父子进程能通讯    

    2.FIFO:任何进程间都能通讯,但速度慢    

    3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题    

    4.信号量:不能传递复杂消息,只能用来同步    

    5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

       本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:

       (1)测试控制该资源的信号量;
       (2)若此信号量的值为正,则允许进行使用该资源,进程将进号量减1;
       (3)若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1);
       (4)当进程不再使用一个信号量控制的资源时,信号量值加1,如果此时有进程正在睡眠等待此信号量,则唤醒此进程。
        套接字通信并不为Linux所专有,在所有提供了TCP/IP协议栈的操作系统中几乎都提供了socket,而所有这样操作系统,对套接字的编程方法几乎是完全一样的

    三、进程/线程同步机制与进程间通信机制比较

    很明显2者有类似,但是差别很大

    同步主要是临界区、互斥、信号量、事件

    进程间通信是管道、内存共享、消息队列、信号量、socket

    共通之处是,信号量和消息(事件)

    小结:

    1. 进程互斥、同步与通信的关系:进程竞争资源时要实施互斥,互斥是一种特殊的同步,实质上需要解决好进程同步问题,进程同步是一种进程通信,由此看来,进程互斥、同步都可以看做进程的通信;
    2. 信号量是进程同步与互斥的常用方法,也可以作为低级的进程通信方法,用于传递控制信号;

    3. 管道与管程是不同的,管程是进程同步的方式,而管道则是进程通信的方式;

    展开全文
  • Java多线程同步机制

    万次阅读 2012-05-16 15:06:42
    thread(线程)、thread-safe(线程安全)、intercurrent(并发的)  synchronized(同步的)、asynchronized(异步的)、  volatile(易变的)、atomic(原子的)、share(共享)  二、总结背景:  一次...
  • 一文搞定c++多线程同步机制

    千次阅读 2020-09-08 21:02:05
    c++多线程同步机制 同步与互斥 现代操作系统都是多任务操作系统,通常同一时刻有大量可执行实体,则运行着的大量任务可能需要访问或使用同一资源,或者说这些任务之间具有依赖性。 线程同步:线程同步是指线程之间...
  • windows系统多线程同步机制原理总结

    千次阅读 2018-12-24 21:24:33
    windows系统多线程同步机制原理总结 同步问题是开发过程中遇到的重要问题之一。同步是要保证在并发执行的环境中各个控制流可以有序地执行,包括对于资源的共享或互斥访问,以及代码功能的逻辑顺序。 为了保证多线程...
  • 一、进程/线程间同步机制。  临界区、互斥区、事件、信号量四种方式 临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别  1、临界区:通过对多线程的串行化来...
  • 从尺寸上讲,同步代码块比同步方法小。你可以把同步代码块看成是没上锁房间里的一块用带锁的屏风隔开的空间
  • Linux线程间同步机制_条件变量

    千次阅读 2016-05-23 16:34:05
    有时看网上的博客自己会纳闷,进程同步机制线程间同步机制分别是什么?  其实进程之间是不用同步机制的,因为进程之间资源不共享,不需要同步机制来对所谓的临界资源进行保护,所以通常我们只讨论进程的...
  • 线程通信针对的是同一个进程的若干子线程之间的通信,由于所有线程共用进程的资源,所以就存在线程安全的问题,多个线程可能同时利用同一段代码,也就是执行结果是不是和预期结果相同的问题。线程安全指的就是...
  • C#多线程同步机制

    千次阅读 2019-01-05 11:54:04
    因为在多线程中对锁进行操作必须是原子的,而++和--不具备这个能力。InterLocked类还提供了两个另外的函数Exchange, CompareExchange用于实现交换和比较交换。Exchange操作会将新值设置到变量中并返回变量的原来值: ...
  • 前言:相信大家在进行Java开发的时候经常会接触到同步的概念,在多线程并发的情况下,为保证同一个时间点只能被一个线程访问到,就需要用到同步机制。想要了解更多关于Java多线程知识,请移步:Android多线程机制...
  • 四种多线程同步机制

    千次阅读 2013-04-06 18:16:34
    1) 因为Critical Sections不是内核对象,所以只能用来同一进程内线程间同步,不能用来个不同进程线程同步。 2) 如果在Critical Sections中间突然程序crash或是exit而没有调用LeaveCriticalSection,则...
  • 线程同步机制

    千次阅读 2018-06-24 01:08:04
    适用范围:临界区在用户模式下,不会发生用户态到内核态的切换,只能用于同进程内线程间同步。其他会导致用户态到- 内核态的切换,利用内核对象实现,可用于不同进程间的线程同步。 性能:临界区...
  • windows多线程同步机制

    千次阅读 2011-12-23 11:01:19
     只能同步同一个进程的线程之间同步,因为临界区不能跨越进程的边界工作。也是因为临界区没有name,所以不能跨进程使用。  访问临界区之前进行锁定,访问后进行解锁。  如果线程B访问线程A锁定的临界区,那么...
  • Linux多线程同步机制

    万次阅读 2011-09-10 21:18:00
    尽管在Posix Thread中同样可以使用IPC的信号量机制来实现互斥锁mutex功能,但显然semphore的功能过于强大了,在Posix Thread中定义了另外一套专门用于线程同步的mutex函数。 1. 创建和销毁  有两种方法创建互斥...
  • 线程同步机制

    千次阅读 2014-11-27 21:33:16
    今天用到一些线程同步机制,故转载线程的四种同步机制如下: 1、 Event 用事件(Event)来同步线程是最具弹性的了。一个事件有两种状态:激发状态和未激发状态。也称有信号状态和无信号状态。事件又分两种类型:...
  • 线程之间同步,除了互斥(前面介绍的互斥锁)之外,还存在协作关系,下面我们就介绍一下java线程常见的一些协作方式。一、内置条件队列正如每个Java对象都可以作为一个内置锁,每个对象也可以作为一个条件队列,...
  • 关于多线程同步的知识点笔记
  • 多进程之间通信方式:  文件映射:本地之间  共享内存:本地之间  匿名管道:本地之间  命名管道:跨服务器  邮件槽:一对多的传输数据,通常通过网络向一台Windows机器传输 ...多线程之间通信方式:  
  • 1、线程各种状态的切换,用图表示的话简单清晰:图出处:https://www.cnblogs.com/bhlsheji/p/5099362.html(博主对每个状态解释的清晰明了)2、为什么需要同步: java允许多线程并发控制,当多个线程同时操作一...
  • Java多线程-同步与锁机制

    千次阅读 2016-06-03 20:06:43
    工作中实践到了多线程与高并发应用,也踩了一些沉重的坑。 万丈高楼起于垒土,学习与总结+工作实践不可相离。分三部分总结这块知识。 知识体系详见第一张思维导图。本篇主题“同步与锁机制”。
  • 多线程技术被设计出来是为了充分利用多核cpu的优势,让cpu
  • JAVA多线程之间实现同步+多线程并发同步解决方案

    万次阅读 多人点赞 2018-03-04 14:09:15
    一、什么是线程安全问题 为什么...案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。/** * 需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。 * Crea...
  • 线程同步能避免出现“race conditions”(竞争条件)和“data corruption”(数据破坏)的情况。 同步(synchronous)与异步(asynchronous)的定义: 当程序1调用程序2时,程序1停下不动,直到程序2完成回到程序1来,...
  • 多线程同步机制的几种方法

    千次阅读 2015-08-10 16:03:09
    线程同步机制 1、 Event 用事件(Event)来同步线程是最具弹性的了。一个事件有两种状态:激发状态和未激发状态。也称有信号状态和无信号状态。事件又分两种类型:手动重置事件和自动重置事件。手动重置事件被...
  • java 多线程同步与线程通信

    千次阅读 2019-07-17 11:25:52
    java多线程同步和通信的方法有如下几种: 1、synchronized关键字修饰方法或代码段,实现数据的互斥访问 2、volatile修饰变量,实现多线程环境下数据的同步 3、ReentrantLock可重入锁,实现数据的互斥访问 3、...
  • (如果多线程程序运行结果和单线程运行的结果是一样的,且相关变量的值与预期值一样,则是线程安全的。) java中与线程同步有关的关键字/类包括: volatile、synchronized、Lock、AtomicInteger等concurrent包下的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 293,042
精华内容 117,216
关键字:

多线程之间的同步机制