精华内容
下载资源
问答
  • 多线程同步和互斥有什么异同

    千次阅读 2018-04-26 10:29:59
    点击打开原文链接线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时...线程互斥可以看成是一种特殊的线程同步线程同步一般...

    点击打开原文链接

    线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。

    线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。线程互斥可以看成是一种特殊的线程同步。

    线程同步一般是当多个线程相互协作,存在相互依赖的关系;

    线程互斥是包括临界资源等的访问,相互线程之间是互斥访问。 

    举个例子,设有一个全局变量global,为了保证线程安全,我们规定只有当主线程修改了global之后下一个子线程才能访问global,这就需要同步主线程与子线程,可用关键段实现。当一个子线程访问global的时候另一个线程不能访问global,那么就需要互斥
    展开全文
  • 所谓同步,是指在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。如果用对资源的访问来定义的...java学习中多线程同步和互斥有哪些实现方法...

    所谓同步,是指在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。如果用对资源的访问来定义的话,同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。java学习中多线程同步和互斥有哪些实现方法

    所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。如果用对资源的访问来定义的话,互斥某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

    当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常。因此多线程同步就是要解决这个问题。线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。

    线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。线程互斥可以看成是一种特殊的线程同步。

    线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。

    用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。内核模式下的方法有:事件,信号量,互斥量。

    展开全文
  • 同步互斥区别   同步:同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒,即他们之间先后关系。 互斥:对于...

    一 同步互斥区别

     

    同步:同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒,即他们之间有先后关系。

    互斥:对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源                                       

    线程互斥可以看成是一种特殊的线程同步

     

    进程(线程)之间的两种关系:同步与互斥。

    所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。

    所谓同步,是指散布在不同进程之间的若干程序片断,它们的运行必须严格按照规定的 某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。

    显然,同步是一种更为复杂的互斥,而互斥是一种特殊的同步。也就是说互斥是两个线程之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行,而同步也是不能同时运行,但他是必须要安照某种次序来运行相应的线程(也是一种互斥)!

    总结

    互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

    同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。

     

    当线程并发执行时,由于资源共享和线程协作,使用线程之间会存在以下两种制约关系。

    (1).间接相互制约。一个系统中的多个线程必然要共享某种系统资源,如共享CPU,共享I/O设备,所谓间接相互制约即源于这种资源共享,打印机就是最好的例子,线程A在使用打印机时,其它线程都要等待。

    (2).直接相互制约。这种制约主要是因为线程之间的合作,如有线程A将计算结果提供给线程B作进一步处理,那么线程B在线程A将数据送达之前都将处于阻塞状态。

    间接相互制约可以称为互斥,直接相互制约可以称为同步,对于互斥可以这样理解,线程A和线程B互斥访问某个资源则它们之间就会产个顺序问题——要么线程A等待线程B操作完毕,要么线程B等待线程操作完毕,这其实就是线程的同步了。因此同步包括互斥,互斥其实是一种特殊的同步

     

    二 同步互斥的方法

     

    分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。

    用户模式下的方法有:原子操作、临界区

    内核模式下的方法有:互斥量、信号量、事件

     

    三 临界区、互斥量、信号量、事件 对比

     

    image

     

    1、关于线程所有权属性:即某个线程获得该同步工具后,在他释放该工具前可以多次进入想访问的资源,一般来说具有所有权属性的工具不用于线程同步,只用于互斥,具体可以参考本文最前面的几篇博客

    2、内核模式下的工具可以用于不同进程的线程之间的同步互斥,用户模式则只能用于相同进程的线程之间

    3、只有互斥量在线程异常退出时,会释放对该工具的所有权,其他线程可以继续获取。其他的工具在线程异常退出时,其占有的工具不会释放,其他线程需要一直等待


    转载:http://www.cnblogs.com/TenosDoIt/p/3602797.html

    展开全文
  • 多线程同步互斥

    2014-09-21 15:35:01
    在进行多线程编程时,难免还要碰到两个问题,那就线程间的互斥与同步: 线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才...
    在进行多线程编程时,难免还要碰到两个问题,那就线程间的互斥与同步:
    
    线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。
    线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。线程互斥可以看成是一种特殊的线程同步(下文统称为同步)。

    线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。
    用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。内核模式下的方法有:事件,信号量,互斥量。
    下面我们来分别看一下这些方法:

    原子操作(全局变量):
    #include " stdafx.h "
    #include
    " windows.h "
    #include
    " stdio.h "

    volatile int ThreadData = 1 ;

    void ThreadProcess()
    {
       
    for(int i=0; i<6; i++)
       
    {
            Sleep(
    1000);
            printf(
    "Sub  Thread Tick %5d!\n",(i+1)*1000);
        }

        ThreadData
    = 0;
        printf(
    "Exit Sub Thread!\n");

    }


    int _tmain( int argc, _TCHAR * argv[])
    {
        HANDLE hThread;
        DWORD ThreadID;
        hThread
    =CreateThread(NULL,
           
    0,
            (LPTHREAD_START_ROUTINE)ThreadProcess,
            NULL,
           
    0,
           
    &ThreadID);

       
    while (ThreadData)
       
    {
            printf(
    "Main Thread is waiting for Sub Thread!\n");
            Sleep(
    600);
        }


        printf(
    "Main Thread Finished! \n");
        system(
    "pause");
       
    return 0;
    }

       在上面的程序中,我利用了全局变量ThreadData来进行线程间的同步,当子线程结束时改变该值,而父线程则循环判断该值来确认子线程是否已经结束,当子线程结束时,父线程才继续进行下面的操作。

    临界区(Critical Section)

    保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。

    临界区包含两个操作原语:
    EnterCriticalSection() 进入临界区
    LeaveCriticalSection() 离开临界区

    EnterCriticalSection()语句执行后代码将进入临界区以后无论发生什么,必须确保与之匹配的LeaveCriticalSection()都能够被执行到。否则临界区保护的共享资源将永远不会被释放。虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。


    事件(Event)
      
    事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。

    信号量包含的几个操作原语:
        CreateEvent()    创建一个信号量
        OpenEvent()    打开一个事件
        SetEvent()    回置事件
        WaitForSingleObject()   等待一个事件
        WaitForMultipleObjects()  等待多个事件

    WaitForMultipleObjects 函数原型:
        WaitForMultipleObjects(
        IN DWORD nCount, // 等待句柄数
        IN CONST HANDLE *lpHandles, //指向句柄数组
        IN BOOL bWaitAll, //是否完全等待标志
        IN DWORD dwMilliseconds //等待时间
        )

    参数nCount指定了要等待的内核对象的数目,存放这些内核对象的数组由lpHandles来指向。fWaitAll对指定的这nCount个内核对象的两种等待方式进行了指定,为TRUE时当所有对象都被通知时函数才会返回,为FALSE则只要其中任何一个得到通知就可以返回。dwMilliseconds在这里的作用与在WaitForSingleObject()中的作用是完全一致的。如果等待超时,函数将返回WAIT_TIMEOUT。
      
    事件可以实现不同进程中的线程同步操作,并且可以方便的实现多个线程的优先比较等待操作,例如写多个WaitForSingleObject来代替WaitForMultipleObjects从而使编程更加灵活。
      
    互斥量(Mutex)
      
    互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。
      
        互斥量包含的几个操作原语:
        CreateMutex()    创建一个互斥量
        OpenMutex()    打开一个互斥量
        ReleaseMutex()    释放互斥量
        WaitForMultipleObjects() 等待互斥量对象
      
    信号量(Semaphores)

    信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。在用CreateSemaphore()创建信号量时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目,不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。

    PV操作及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用共享资源的进程数。

    P操作申请资源:
        (1)S减1;
        (2)若S减1后仍大于等于零,则进程继续执行;
        (3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转入进程调度。

    V操作释放资源:
        (1)S加1;
        (2)若相加结果大于零,则进程继续执行;
        (3)若相加结果小于等于零,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转入进程调度。
      
        信号量包含的几个操作原语:
        CreateSemaphore()  创建一个信号量
        OpenSemaphore()  打开一个信号量
        ReleaseSemaphore()  释放信号量
        WaitForSingleObject()  等待信号量
      

    信号量的使用特点使其更适用于对Socket(套接字)程序中线程的同步。例如,网络上的HTTP服务器要对同一时间内访问同一页面的用户数加以限制,这时可以为每一个用户对服务器的页面请求设置一个线程,而页面则是待保护的共享资源,通过使用信号量对线程的同步作用可以确保在任一时刻无论有多少用户对某一页面进行访问,只有不大于设定的最大用户数目的线程能够进行访问,而其他的访问企图则被挂起,只有在有用户退出对此页面的访问后才有可能进入。

    因为它们的使用方法都很类似,下面我结合起来给出一个简单的示例:

    #include " stdafx.h "
    #include
    " windows.h "
    #include
    " stdio.h "

    volatile int ThreadData = 1 ;

    CRITICAL_SECTION csPrint;
    // 临界区
    // HANDLE evtPrint; // 事件信号,标记事件是否已发生
    // HANDLE mtxPrint; // 互斥信号,如有信号表明已经有线程进入临界区并拥有此信号
    // HANDLE smphPrint; // 信号量,表示是否已经达到允许的最大线程数

    void Print( char * str)
    {
        EnterCriticalSection(
    &csPrint); // 进入临界区
       
    //WaitForSingleObject(evtPrint, INFINITE); // 等待事件有信号
       
    //WaitForSingleObject(mtxPrint, INFINITE); // 等待互斥量空置(没有线程拥有它)
       
    //WaitForSingleObject(smphPrint, INFINITE); // 等待对共享资源请求被通过 等于 P操作

       
    for (;*str != '\0';str++)
       
    {
            Sleep(
    50);
            printf(
    "%c",*str);
        }

        printf(
    "\n");

        LeaveCriticalSection(
    &csPrint); // 退出临界区
       
    //SetEvent(evtPrint); // 把事件信号量恢复,变为有信号
       
    //ReleaseMutex(mtxPrint); // 释放对互斥量的占有
       
    //ReleaseSemaphore(smphPrint, 1, NULL); // 释放共享资源 等于 V操作

    }


    void ThreadProcess()
    {
       
    for(int i=0; i<6; i++)
       
    {
            Sleep(
    1000);
            Print(
    "Sub  Thread is running!");
        }

        ThreadData
    = 0;

    }


    int _tmain( int argc, _TCHAR * argv[])
    {
        HANDLE hThread;
        DWORD ThreadID;

        InitializeCriticalSection(
    &csPrint); // 初始化临界区
       
    //evtPrint = CreateEvent(NULL, FALSE, TRUE, L"PrintEvent"); // 初始化事件
       
    //mtxPrint = CreateMutex(NULL, FALSE, L"PrintMutex"); // 初始化互斥量
       
    //smphPrint= CreateSemaphore(NULL, 1, 1, L"PrintSemaphore"); // 设置信号量1个资源,因此同时只可以有一个线程访问

        hThread
    =CreateThread(NULL,
           
    0,
            (LPTHREAD_START_ROUTINE)ThreadProcess,
            NULL,
           
    0,
           
    &ThreadID);

       
    while (ThreadData)
       
    {
            Print(
    "Main Thread is waiting for Sub Thread!");
            Sleep(
    600);
        }


        printf(
    "Main Thread Finished!");
        system(
    "pause");
       
    return 0;
    }


       综上所述:当在同一进程中的多线程同步时,临界区是效率最最高,基本不需要什么开销。而内核对象由于要进行用户态和内核态的切换,开销较大,但是内核对象由于可以命名,因此它们同时可以用于进程间的同步。另外,值得一提的是,信号量可以设置允许访问资源的线程或进程个数,而不仅仅是只允许单个线程或进程访问资源。

    展开全文
  • 点击打开原文链接线程间的同步方法大体可分为两类:用户模式内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性...1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问...
  • 实现线程同步互斥的四种方式   临界区(Critical Section):适合一个进程内的多线程访问公共区域或代码段时使用  互斥量 (Mutex):适合不同进程内多线程访问公共区域或代码段时使用,与临界区相似。
  • Java 线程同步和互斥

    2021-07-21 11:12:41
    所谓互斥,就是不同线程通过竞争进入临界区(共享的数据硬件资源),为了防止访问冲突,在有限的时间内只允许其中之一独占性的使用共享资源。如不允许同时写 同步关系则是线程彼此合作,通过一定的逻辑关系来...
  • 通俗易懂说-多线程同步(2)互斥量1. 互斥量定义2. 接口(Windows实现)3. 接口(Linux实现)4. 例子 1. 互斥量定义 互斥量用来确保一个线程独占一个资源的访问。 互斥量是一个内核对象。 互斥量与临界区非常相似,...
  • 1. 线程同步: 指线程之间所具有的一种制约关系,一个线程的执行依赖另外一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。 2. 线程互斥: 指对于共享的进程系统资源,每个线程访问...
  • 互斥锁,是一种信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源。可以保证以下三点: 原子性:把一个互斥量锁定为一个原子操作,这意味着操作系统(或pthread函数库)保证了如果一个线程锁定了一个...
  • Linux多线程同步互斥条件变量

    千次阅读 2016-03-30 23:30:50
    1. 什么是互斥量 ...如果释放互斥锁时有多线程阻塞,所以在该互斥锁上的阻塞线程都会变成可进行状态,第一个变成运行状态的线程可以对互斥量加锁,其他线程在次被阻塞,等待下次运行状态。 pthr
  • 写在前面 本文全文以售票系统为例,简诉了java多线程间共享数据的两种方式、线程同步。文章可能还有很多不足,请大家谅解,欢迎大佬提...线程同步互斥2.1 上述代码存在的问题2.2 同步与互斥2.3 synchronized实现...
  • 所以线程间通信容易进行,但是多线程同时访问共享对象时需要引入同步和互斥机制。 线程同步 线程的同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应...
  • 此代码参考博客:... 一个经典的多线程同步问题 //win 多线程 #define THREAD_NUM 10 int threadCount=0; int threadNO=0; //用于互斥 CRITICAL_SECTION NOCritical
  • 线程同步互斥线程同步的方式
  • 面试被问到线程同步,发现对于概念并不清楚,网上查阅...所谓互斥,就是不同线程通过竞争进入临界区(共享的数据硬件资源),为了防止访问冲突,在有限的时间内只运行其中之一独占性的使用共享资源,如不允许同时
  • MFC多线程同步互斥

    2014-04-02 16:48:50
    MFC多线程同步互斥[转载] 标签: thread mfc 多线程 互斥 分类: MFC心得 原文地址:http://blog.csdn.net/muchforest/article/details/1817013  现在流行的进程线程同步互斥的控制机制,其实是由最原始最基本的4...
  • 线程同步互斥

    2013-09-26 11:02:13
    为了解决多线程之间对资源访问的同步和互斥问题,我们需要了解线程同步机制。 第一种机制:互斥互斥锁是一种简单的加锁方法,可以使单个线程进行对资源访问的原子操作。 互斥锁的基本操作就是加锁解锁。互斥锁...
  • 多线程同步和互斥简介  在做项目时,难免会碰到多线程问题,在进行多线程编程时,难免会遇到多线程互斥同步操作。 线程的同步就是协同步调,按预定的先后次序进行运行。如:你说完...
  • 多线程同步互斥(3)

    万次阅读 2012-02-02 10:02:07
    在进行多线程编程时,难免还要碰到两个问题,那就线程间的互斥与同步: 线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才...
  • C++多线程并发(二)---线程同步互斥

    万次阅读 多人点赞 2019-03-20 00:08:29
    一、何为线程同步 在前一篇文章《C++多线程并发编程(一)—线程管理》中解释多线程并发时说到两个比较重要的概念: 多线程并发:在同一时间段内交替处理多个操作,线程切换时间片是很短的(一般为毫秒级),一个...
  • 相交进程之间的关系主要两种,同步互斥。所谓互斥,是指散步在不同进程之间的若干2113程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它 们之中的任一程序片段,只能等到该进程运行完这个程序...
  • 今天我们来分享一下,线程同步互斥——互斥锁的实现。  多个线程同时访问共享数据时可能会产生冲突,造成程序运行结果不是我们所预期的结果。  不产生冲突的多线程访问情况,代码截图如下:      产生冲突...
  • 在使用boost库实现线程同步之前,我们先了解一下下面的概念: 对于互斥可以这样理解,线程A线程B互斥访问某个资源则它们之间就会产个顺序问题——要么线程A等待线程B操作完毕,要么线程B等待线程操作完毕,这其实...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 96,686
精华内容 38,674
关键字:

多线程同步和互斥有何异同