精华内容
下载资源
问答
  • 信号量和临界区

    2008-09-10 09:51:00
    学习目标:学习信号量及其属性进行同步实验研究临界区的行为使用POSIX命名信号量和无名信号量理解信号量的管理1. 临界区临界区是指必须以互斥的方式执行的代码段,也就是说临界区范围内只能由一个活动的线程。例如:...
      
    
    学习目标:
    学习信号量及其属性
    进行同步实验
    研究临界区的行为
    使用POSIX命名信号量和无名信号量
    理解信号量的管理
    1. 临界区
    临界区是指必须以互斥的方式执行的代码段,也就是说临界区范围内只能由一个活动的线程。
    例如:修改共享变量的过程中其他的执行线程可能会访问共享变量,那么修改共享变量的代码就被看成是临界区的一部分。
    临界区问题指用安全、公平和对称的方式来执行临界区代码的问题
    2. 信号量
    信号量是(S)一个整型变量,它带有两个原子操作信号量锁定wait和信号量解锁signal。
    可以将其看成一个整数值和一个等待signal操作的进程列表。
    wait操作:如果S大于零,wait就在一个原子操作中测试S,并对其进行减量运算;
                  如果S等于零,wait就在一个原子操作中测试S,并阻塞调用程序。
    signal操作:如果有线程在信号量上阻塞,S就等于零,signal就会解除对某个等待线程的阻塞;
                         如果没有线程在信号量上阻塞,signal就对S进行增量运算。
    信号量作用:
    a:保护临界区
    wait(&s)
    <critical section>
    signal(&s);
    <remainder section>
    b:线程同步
    process 1 executes:           process 2 executes:
    a;                          wait(&sync);
    signal(&sync);                b;
    3. POSIX:SEM无名信号量
    信号量是一个sem_t类型的变量,有相关的原子操作来对它的值进行初始化、增量和减量操作。如果一个实现在unistd.h中定义了_POSIX_SEMAPHORES,那么这个实现就支持POSIX:SEM信号量。无名信号量和命名信号量之间的区别类似于普通管道和命名管道之间的区别
    信号量的申明:
    #include <semaphore.h>
    sem_t sem;
    信号量的初始化:必须在使用信号量之前对其进行初始化
    #include <semaphore.h>
    int sem_init(sem_t *sem, int pshared, unsigned value);
    没有规定成功时返回值,不成功返回-1并设置errno,必须检测的错误码:
    EINVAL value大于SEM_VALUE_MAX
    ENOSPC 初始化资源已经耗尽,或者信号量的数目超出了SEM_NSEMS_MAX的范围
    EPERM 调用程序不具有适当的特权
    参数pshared等于0,说明信号量只能由初始化这个信号量的进程中的线程使用;
    如果pshared非零,任何可以访问sem的进程都可以使用这个信号量。
    注:在创建信号量之后创建一个子进程,并没有提供对信号量的访问,子进程收到的是信号量的拷贝,而不是真的信号量。
    例:创建一个有进程中的线程使用的信号量
    sem_t semA;
    if (sem_init(&semA, 0, 1) == -1 )
    {
    perror (“failed to initialize semaphore semA”);
    }
    信号量的销毁:
    #include <semaphore.h>
    int sem_destroy(sem_t *sem);
    成功返回0,不成功返回-1并设置errno,检测错误码:
    EINVAL sem不是有效的信号量
    例:
    if (sem_destroy(&semA) == -1)
    {
    perror (“Failed to destroy semA”);
    }
    POSIX申明:销毁一个已经销毁的信号量的结果是未定义的。有其他线程阻塞在一个信号量上时,销毁这个信号量的结果也是未定义的。
    4. POSIX:SEM信号量的操作
    这里描述的信号量的操作适用与无名信号量,同时也适用命名信号量
    signal操作:
    #include <semaphore.h>
    int sem_post(sem_t *sem);
    成功返回0,不成功返回-1并设置errno,必须检测的错误码:
    EINVAL *sem不对应有效的信号量
    函数sem_init是信号安全的,可以在信号处理程序中调用它。
    wait操作:
    #include <semaphore.h>
    int sem_trywait(sem_t *sem);
    int sem_wait(sem_t *sem);
    成功返回0,不臣工返回-1并设置errno,必须检测的错误码
    EINVAL   *sem不对应有效的信号量
    EAGAIN   函数sem_trywait不会阻塞,而是设置errno后返回
    EINTR     被信号中断
    如果信号量为0,则调用进程一直阻塞直到一个相应的sem_post调用解除了对它的阻塞为止,或者直到它被信号中断为止(被信号中断后必须手动重启)。
    #include <errno.h>
    #include <semaphore.h>
    static int   shared     = 0;
    static sem_t sharedsem;
    int initshared(int val)
    {
        if (sem_init(&sharedsem, 0, 1) == -1)
        {
            return -1;
        }
        shared = val;
        return 0;
    }
    int getshared(int *val)
    {
        while (sem_wait(&sharedsem) == -1)   //必须考虑被信号中断,重启的情况
        {
            if (errno != EINTR)
                return -1;
        }
        *val = shared;
        return sem_post(&sharedsem);    //信号安全的,无须考虑
    }
    int incshared()
    {
        while (sem_wait(&sharedsem) == -1)
        {
            if (errno != EINTR)
                return -1;
        }
        shared++;
        return sem_post(&sharedsem);
    }
    注:如果既要在main程序中,又要在信号处理程序中对一个变量进行增量操作,如何用上面的程序保护着个变量?
    如果不做一些其他的操作,使不能用它来保护这个变量的。如果信号是在上面程序中的某个函数调用锁定了信号量的时候被捕捉到的,那么在信号处理程序中对这些函数中的某一个进行调用的时候,就会引起死锁
    正确的做法是在调用getshared和incshared之前将信号阻塞,调用完成后,解除信号阻塞。
    例:创建一个信号量,并将其传递给多个线程,线程函数调用信号量保护临界区
    #include <semaphore.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define TEN_MILLION   10000000L
    #define BUFSIZE       1024
    void *threadout(void *args)
    {
        char             buffer[BUFSIZE];
        char             *c;
        sem_t            *semlockp;
        struct timespec sleeptime;
        semlockp          = (sem_t *)args;
        sleeptime.tv_sec = 0;
        sleeptime.tv_nsec = TEN_MILLION;
        snprintf (buffer, BUFSIZE, "This is a thread from process %ld/n",
                        (long)getpid());
        c = buffer;
    //临界区入口
        while (sem_wait(semlockp) == -1)
        {
            if (errno != EINTR)
            {
                fprintf (stderr, "Thread failed to lock semaphore/n");
                return NULL;
            }
        }
    //临界区
        while (*c != '/0')
        {
            fputc (*c, stderr);
            c++;
            nanosleep(&sleeptime, NULL); //非忙等循环
        }
    //临界区出口
        if (sem_post(semlockp) == -1)
        {
            fprintf (stderr, "Thread failed to unlock semaphore/n");
        }
        return NULL;
    }
    int main(int argc, char *argv[])
    {
        int       error;
        int       i;
        int       n;
        sem_t     semlock;
        pthread_t *tids;
        if (argc != 2)
        {
            fprintf (stderr, "Usage: %s numthreads/n", argv[0]);
            return 1;
        }
        n    = atoi (argv[1]);
        tids = (pthread_t *)calloc(n, sizeof(pthread_t));
        if (tids == NULL)
        {
            perror ("Failed to initialize semaphore");
            return 1;
        }
        if (sem_init(&semlock, 0, 1) == -1)
        {
            perror ("Failed to initialize semaphore");
            return 1;
        }
        for (i=0; i<n; i++)
        {
            error = pthread_create(tids+i, NULL, threadout, (void *)&semlock);
            if (error != 0)
            {
                fprintf (stderr, "Failed to create thread:%s/n", strerror(error));
                return 1;
            }
        }
        for (i=0; i<n; i++)
        {
            error = pthread_join(tids[i], NULL);
            if (error != 0)
            {
                fprintf (stderr, "Failed to join thread:%s/n", strerror(error));
                return 1;
            }
        }
        return 0;
    }
    注:sem_init(&semlock, 0, 1) 将semlock初始化为1,如果0的话将产生死锁。
    stderr 标准输出是排他性资源,同时只能由一个线程使用。
    如果改称sem_init(&semlock, 0, 2),程序输出将会混乱。
    检测命名信号量和无名信号量的值:
    #include <semaphore.h>
    int sem_getvalue(sem_t *restrict sem, int *restrict sval);
    成功返回0,不成功返回-1并设置errno,必须检测错误码:
    EINVAL   *sem不对应一个有效的信号量
    函数可以用来检测一个命名信号量或者无名信号量的值。
    5. POSIX:SEM命名信号量
    命名信号量用来同步那些不共享内存的进程。
    命名信号量和文件一样,有一格名字、有一个用户ID、一个组ID和权限。
    如果两个进程(线程)打开的信号量一“/”开头,则其引用同一个信号量。
    因此,通常都要为POSIX:SEM命名信号量使用以“/”开头的名字。
    5.1创建并打开命名信号量
    #include <semaphore.h>
    sem_t *sem_open( const char *name, int oflag, ...);
    成功返回信号量的地址,不成功返回SEM_FAILED并设置errno,必须检测的错误码:
    EACCES            权限不够
    EEXIST             设置了O_CREATE和O_EXCL,而且信号量存在
    EINTR              函数别信号中断
    EINVAL             name不能作为信号量打开、或者试图用大于SEM_VALUE_MAX的值创建信号量
    EMFILE             进程使用了太多的文件描述符或信号量
    ENAMETOOLONG   name比PATH_MAX长、或者它有一个组件超出NAME_MAX范围
    ENFILE             系统中打开了太多的信号量
    ENOENT            没有设置O_CREATE,而且信号量也不存在
    ENOSPC            没有足够的空间了创建信号量
    函数sem_open功能说明:
    参数oflag用来确定是创建信号量,还是仅仅由函数对其进行访问。
    如果参数oflag设置了O_CREATE比特位就必须设置mode位(mode_t类型的权限位)和value位(unsigned类型的信号量初始值)。
    如果O_CREATE和O_EXCL位都设置了,那么信号量已经存在的话,函数返回一个错误。
    如果仅仅设置了O_CREATE位,那么信号量如果存在,信号量会忽略O_CREATE和其他额外的参数
    在信号量已经存在的情况下,POSIX没有提供直接设置命名信号量值得方法
    例:访问一个命名信号量,如果不存在就创建它
    #include <errno.h>
    #include <semaphore.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #define PERMS (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
    #define FLAGS (O_CREAT | O_EXCL)
    #define BUFSIZE 1024
    int getnamed(char *name, sem_t **sem, int val)
    {
        while ( ((*sem = sem_open(name, FLAGS, PERMS, val)) == SEM_FAILED) &&
            (errno == EINTR));    //创建命名信号量,遇信号中断重启
        if (*sem != SEM_FAILED)   //创建成功返回
            return 0;
        if (errno != EEXIST)     //失败返回,已经存在执行读取
            return -1;
                                 //信号量已经存在,读取它
        while ( ((*sem = sem_open(name, 0)) == SEM_FAILED) && (errno == EINTR));
        if (*sem != SEM_FAILED)
            return 0;
        return -1;
    }
    int main(int argc, char *argv[])
    {
        char         buffer[BUFSIZE];
        char         *c;
        pid_t        childpid         = 0;
        int           delay;
        volatile int dummy            = 0;
        int          i;
        int          n;
        sem_t        *sem_lockp;
        if (argc != 4)
        {
            fprintf (stderr, "Usage: %s processes delay semaphorename/n", argv[0]);
            return 1;
        }
        n     = atoi(argv[1]);
        delay = atoi(argv[2]);
        for (i=1; i<n; i++)
        {
            if (childpid = fork())
                break;               //重要,不能少,子进程推出循环,父进程继续执行循环
           
        }
        snprintf (buffer, BUFSIZE, "i:%d process ID:%ld parent ID:%ld child ID:%ld/n",
                                       i, (long)getpid(), (long)getppid(), (long)childpid);
        c = buffer;
        if (getnamed(argv[3], &sem_lockp, 1) == -1)
        {
            perror ("Failed to create named semaphore");
            return 1;
        }
        while (sem_wait(sem_lockp) == -1)             //进入临界区
        {
            if (errno != EINTR)
            {
                perror("Failed to lock semlock");
                return 1;
            }
        }
        while (*c != '/0')                  //临界区
        {
            fputc (*c, stderr);
            c++;
            for (i=0; i<delay; i++)
                dummy++;
        }
       
        if (sem_post(sem_lockp) == -1)          //退出临界区
        {
            perror("Failed to unlock semlock");
            return 1;
        }
        if (wait(NULL) == -1)                 //等待子进程结束返回
            return 1;
        return 0;
    }
    注1:命名信号量就像文件一样存在系统中的。如果同时运行两个以上程序在一台机器上,则还能够正常运新
    注2:如果上面的程序正在运行,输入Ctrl-C退出,然后再次运行它,又可能进程都会阻塞,因为Ctrl-C产生的信号有可能在信号量的值为0时被传递。下次运行程序时,信号量的初始值是0,所以所有的进程阻塞。
    命名信号量使多个进程可以实现同步和互斥,无名信号量使同一个进程的多个线程实现同步和互斥。
    5.2关闭并删除命名信号量
    与命名管道一样,命名信号量在单个程序的执行之外是具有持久性的。
    关闭信号量:
    #include <semaphore.h>
    int sem_close(sem_t *sem);
    成功返回0,不成功返回-1并设置errno,检测错误码:
    EINVAL   *sem不是一个有效的信号量
    删除命名信号量:
    #include <semaphore.h>
    int sem_unlink(const char *name);
    成功返回0,不成功返回-1并设置errno,检测错误码:
    EACCES             权限不正确
    ENAMETOOLONG    name比PATH_MAX长、或者它有一个组件超出NAME_MAX范围
    ENOENT             信号量不存在
    说明1:函数在素有的进程关闭了命名信号量之后将命名信号量从系统中删除。当进程显示地调用SEM_CLOSE、_exit、exit、exec或执行从main的返回式,就会出现关闭操作。
    说民2:sem_unlink之后,即使其他的进程仍然将老的信号量打开着,用相同的名字调用的sem_open引用的也是新的信号量。即使其他的进程将信号量打开着,sem_unlink函数也总是会立即返回。
    例:关闭并删除命名信号量的函数
    #include <semaphore.h>
    #include <errno.h>
    int destroynamed(char *name, sem_t *sem)
    {
        int error = 0;
        if (sem_close(sem) == -1)
            error = errno;
       
        if ( (sem_unlink(name) != -1) && !error)
            return 0;
       
        if (error != 0)
            errno = error;
       
        return -1;
    }
    注:命名信号量具有持久性的。如果创建了这样的一个信号量,即使创建它的进程和所有可以访问它的进程都终止了,它还是一直存在于系统中,保持它的值直到被销毁为止。
    POSIX没有提供方法来确定那些命名信号量是存在的。当显示目录内容是,他们又可能会出现,也有可能不出现。当系统重启时,他们有可能被销毁,也可能不被销毁。
     
     
    展开全文
  • 临界区(Critical Section) 仅允许一个线程同时访问同享资源,进程内使用。需要资源少,速度快。如果共享资源只使用于同一进程内,推荐使用临界区。 互斥量(Mutex) 仅允许一个线程同时访问同享资源。创建互斥...

    临界区(Critical Section)

    仅允许一个线程同时访问同享资源,进程内使用。需要资源少,速度快。如果共享资源只使用于同一进程内,推荐使用临界区。

    互斥量(Mutex)

    仅允许一个线程同时访问同享资源。创建互斥量可以命名,所以可跨进程使用。需要资源多于临界区。

    信号量(Semaphore)

    允许一个或多个线程中有限数量的线程同时访问共享资源,可跨进程使用。

    事件(Event)

    用于一个线程通知另一个线程某事件发生,可跨进程使用。

    展开全文
  • VC MFC中线程同步对象的区别  临界区 CCriticalSection,在用户模式工作,适用于保护线程间共享资源,一...互斥量 CMutex,在内核模式工作,除了支持临界区的功能,还可以为互斥量命名,以便在多进程中工作。互...

    原文: http://blog.csdn.net/zmq5411/article/details/6113414

    VC MFC中线程同步对象的区别 

    临界区 CCriticalSection,在用户模式工作,适用于保护线程间共享资源,一个线程可以多次Lock不会出错。不支持在多进程之间工作。

    互斥量 CMutex,在内核模式工作,除了支持临界区的功能,还可以为互斥量命名,以便在多进程中工作。互斥量比临界区耗资源。

    事件  CEvent,在内核模式工作,适用于一个线程等待另一个线程完成某任务。

    信号量 CSemaphore,在内核模式工作,适用于允许特定个数的线程执行某任务。

     

    实例:
    CwinThread *pThread;

    1、使用互斥对象
       HANDLE hMutex;

       hMutex = CreateMutex(NULL , false, "mutex");
      
     
       线程函数使用:
       WaitForSingleObject(hMutex,INFINITE);
       {
       }
       ReleaseMutex(hMutex);


       <2>
       CMutex Section;
       线程函数中使用
       CsingleLock singlelock;
       singlelock(&Section);
       singlelock.lock();
       singlelock.Unlock();
      

        
    2、使用事件对象
      
       1 > 第一种实用方式:
       HANDLE hEvent;

       线程函数中使用:
       WaitForSingleObject(hEvent,INFINITE);
       {
       }
       SetEvent(hEvent);

       hEvent = CreateEvent(NULL,FALSE,TRUE,"event");//自动重置对象,通知状态
       SetEvent(hEvent);//为通知状态
       ResetEvent(hEvent);//未通知状态
     
     
    3、实用临界区对象
      
       <1>
       CRITICAL_SECTION  Section;
      
       InitializeCriticalSection(&Section);

       线程中实用
       EnterCriticalSection(&Section);
       {
       }
       LeaveCriticalSection(&Section);
       <2>
       
       CCriticalSection Section;
      
       线程中使用
       Section.Lock();
       Section.Unlock();


    4、线程启动
      pThread = AfxBeginthread(thradfunction,hwnd);
      pThread->m_bAutoDelete = FALSe;//线程为手动删除

      在OnDestory()
      {
        WaitForSingleObject(pThread->m_hThread,INFINITE);//等待线程的结束
        delete pThread;
      }
    5、线程通讯
       1> ::PostMessage((HWND),WM_USERMSG,0,0);
       2> CwinThread::PostThradMessage();

        使用事件对象
     2 >Cevent threadStart,threadEnd;
         UINT ThreadFunction(LPVOID pParam)
         {
          ::WaitForSingleObject(threadStart.m_hObject,INFINITE);
          Sleep(1000);
          ::WaitForSingleObject(threadEnd.m_hObject,INFINITE);
          ::PostMessage(hWnd,WM_USERMSG,0,0);
         }
        
         A()
         {
              threadStart.SetEvent();
              pThread = AfxBeginThread(ThreadFunction,hWnd);
              pThread->m_bAutoDelete = FALSE;
              delete pThread;
         }

    6、使用信号量,可以同时让多个线程共访同一个资源
       Csemaphor *semaphore;
       semaphore = new Csemaphore(2,2);
       线程函数中使用:
       Csinglelock singleLock(semahore);
       singlelock.Lock();


    (二)、项目中使用
    1、使用全局的线程调用,(使用信号量 CRITICAL_SECTION   g_Send_EMM_Cs;)
    在一个文件中如:Scrambler.cpp中
    InitializeCriticalSection(&g_Send_EMM_Cs);//需要初始化
    //发送CW到ECMG A线程
    UINT SendCWToECMGAThread(LPVOID lParam)
    {
    EnterCriticalSection(&g_Send_EMM_Cs);
    {
      
    }
    LeaveCriticalSection(&g_Send_EMM_Cs);
    }

    可以在其他文件中(如Fmain.cpp中调用)
    AfxBeginThread(SendCWToECMGAThread, pDoc);

    需要在StdAfx.h中声明
    extern UINT SendCWToECMGAThread(LPVOID lParam);

    2、使用类内部调用(使用WINAPI)
    在MainFrm.h中声明:
    static DWORD WINAPI ConnectServerOutTime(LPVOID lpParameter);//连接服务器线程超时
    在MainFrm.cpp中调用
    HANDLE hTreadTime;
    hTreadTime = CreateThread(NULL,0,CMainFrame::ConnectServerOutTime,NULL,0,NULL);
    hMutex = CreateMutex(NULL,TRUE,NULL);//创建互斥
    CloseHandle(hTreadTime);
    则会执行:
    //启动的线程
    DWORD WINAPI CMainFrame::ConnectServerOutTime(LPVOID lpParameter)
    {
        if( WAIT_TIMEOUT == WaitForSingleObject(hMutex,2000) )超时两秒
        return 0 ;
    }

    3、使用事件句柄
    HANDLE      g_hEcmEvent[3];
    g_hEcmEvent[0] = CreateEvent(NULL,TRUE,FALSE,NULL);//创建事件
    UINT SendCWToECMGAThread(LPVOID lParam)
    {
     if(WaitForSingleObject(g_hEcmEvent[0], 4000) == WAIT_OBJECT_0)
     {
     
     }
    }
    可以在其他地方:
    SetEvent(g_hEcmEvent[0]);
    ResetEvent(g_hEcmEvent[0]);

    展开全文
  • 临界区、互斥量、信号量

    千次阅读 2016-03-02 08:42:35
    互斥量、信号量是有命名的,因此它可以跨进程使用。
    临界区(Critical Section)(临界资源是一次仅允许一个进程使用的共享资源)
    如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起。


    信号量(Semaphores)
    有N个进程共享同一临界资源,用信号量机制可以实现对一临界资源的互斥访问。
    信号允许多个线程同时使用共享资源。是一种资源计数器。


    互斥量(Mutex)
    互斥(Mutex)是一种内核对象。能够保证多个线程对同一共享资源的互斥访问。
    同临界区有些类似,只有拥有互斥对象的线程才具有访问资源的权限。


    总结:

        1.互斥量与临界区的作用非常相似,但互斥量是有命名的,因此它可以跨进程使用。
        2. 如果只为了在进程内部是用的话,使用临界区会带来速度上的优势并能够减少资源占用量。(临界区 VS 互斥量)
        3. 互斥量(Mutex),信号量(Semaphore)都可以跨进程使用。
           因为互斥量、信号量是跨进程的,它们一旦被创建,就可以通过名字打开它。(这里因果好像弄反了?



    使用命名对象要注意的问题

    1 为了防止名字的冲突,建议创建一个GUID ,用作对象名。 //GUID虽然是唯一,但另外的进程怎样知道该对象的GUID?


    2 当调用一个用于创建内核对象的函数时,该函数就返回一个用于标识该对象的句柄。如果将该句柄值传递给另一个进程P1(中的一个线程),

      那么当P1使用这个内核对象的句柄值时,调用就会失败。(程序会闪退)



    3 要确定一个对象是否属于内核对象,最容易的方法是观察创建该对象所用的函数。



    4 例如,CreateFileMapping函数可使系统能够创建一个文件映射对象。每个内核对象只是内核分配的一个内存块,并且只能由该内核访问。





    什么是线程安全? 线程安全是怎么完成的(原理)? 


    线程安全就是说多线程访问同一代码,不会产生不确定的结果。编写线程安全的代码是低依靠线程同步。


    在多线程环境中,当各线程不共享数据的时候,那么一定是线程安全的。


    问题是这种情况并不多见,在多数情况下需要共享数据,这时就需要进行适当的同步控制了,如使用临界区,互斥量,信号量等进行同步控制。



    展开全文
  • 命名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。 信号量(semophonre): 信号量是一个计数器,可以用来控制多个进程队共享资源的访问。它常作为一个锁机制,防止某进程在访问共...
  • 作用:临界区控制器确保其子节点下的取样器或控制器将被执行(只有一个线程作为一个锁)确保它的子元素(samplers /控制器等)在执行控制器的子程序之前只执行一个线程作为指定的锁。2.添加 线程-添加逻辑控制器-临界...
  • [MFC]MFC同步类总结

    千次阅读 2013-05-09 21:14:39
    MFC同步类 CCriticalSection临界区:在用户模式工作(遇到加锁等待时会进入内核模式),使用与...CMutex互斥量:在内核模式工作,除支持临界区的功能外,还可以为互斥量命名,以便在多进程中工作。互斥量比临界区
  • 临界区是每个进程中访问临界资源的那段代码称,每次只准许一个进程进入临界区,进入后不允许其他进程进入。不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。它可以作为线程间通信方式而不能...
  • 文章目录进程同步临界资源临界区同步和互斥信号量互斥量经典进程同步问题生产者消费者问题读者写者问题进程通信匿名管道通信命名管道通信(FIFO)信号信号量共享存储套接字消息队列 进程同步 临界资源 一次仅允许一个...
  • CSemaphore/CMutex/CCriticalSection... 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上
  • 它的作用是保证只有一个线程可以申请到该对象 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会...
  • 【Linux】匿名管道

    2019-01-17 22:54:46
    概念 一提到管道,我们都知道,它是Linux中最... 临界区:我们把访问临界资源的那部分代码叫做临界区 互斥:在任意时刻,只允许有一个进程进入临界资源进行资源访问并且在访问期间,其它进程不得访问,这就是互斥...
  • Mutex互斥内核对象

    2011-08-14 17:44:35
    对于互斥的效果,其实临界区(CRITICAL_SECTION)也实现了。它俩的区别在于互斥对象属于内核对象,而临界区属于用户模式对象。临界区只能适用于同一个进程之间的多个线程的同步,而互斥对象可以适用于不同进程间线程的...
  • VC线程同步方法

    2019-09-26 01:43:08
    互斥量 CMutex,在内核模式工作,除了支持临界区的功能,还可以为互斥量命名,以便在多进程中工作。互斥量比临界区耗资源。 事件 CEvent,在内核模式工作,适用于一个线程等待另一个...
  •  互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。因为...
  • 进程通信

    2018-04-11 14:07:47
    Linux 进程间通信的8种方式:1 管道2 命名管道3 内存映射4 消息队列5 共享内存6 信号量7 信号8 套接字临界区是每个进程中访问临界资源的那段代称,每次只准许一个线程进入临界区,进入后不允许其他线程进入(线程...
  • 同步对象之间的区别  MFC对象:CSemaphore/CMutex/CCriticalSection/... 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了
  • 进程同步方式:临界区,互斥量,信号量,事件。 线程同步方式:信号量,互斥量,条件变量。 进程通信方式:管道(普通管道和命名管道),消息队列,信号量,信号,共享内存,套接字。 线程通信方式:临界区,互斥量,...
  • 互斥量相对于临界区更为高级,可以对互斥量进行命名,支持跨进程的线程同步。互斥量是调用的Win32的API对互斥锁的操作,因此在同一操作系统下不同进程可以按照互斥锁的名称共享锁。 正因为如此,互斥锁的操作会更好...
  • 线程同步对象的区别

    2008-05-16 00:35:00
     互斥量 :在内核模式工作,除了支持临界区的功能,还可以为互斥量命名,以便在多进程中工作。互斥量比临界区耗资源。A mutex object is a synchronization object whose state is set to signaled ...
  • 互斥量 CMutex,在内核模式工作,除了支持临界区的功能,还可以为互斥量命名,以便在多进程中工作。互斥量比临界区耗资源。 事件 CEvent,在内核模式工作,适用于一个线程等待另一个线程完成某任
  • 线程同步机制

    2012-07-06 19:57:54
    1.互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。因为...
  • 无名信号量

    千次阅读 2013-01-08 11:26:04
    在POSIX标准中,信号量分两种,一种是无名信号量,一种是...它比起互斥锁功能更强大,互斥锁只是用来排他性访问临界区和共享资源,当一个线程要访问临界区或共享资源时,就必须先加锁,访问完成后再解锁,也就是说,加
  • 本文原址:http://www.cppblog.com/dragon/archive/2008/09/02/60733.aspx作者:...   互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更
  • 管道用于进程间的通信,进程间通信的 公共资源叫做临界资源,访问临界资源的代码叫做临界区 。管道文件以p开头,管道是一种最基本的IPC机制 管道又有匿名管道和命名管道之分匿名管道: 调用pipe函数时在内核开辟一...

空空如也

空空如也

1 2 3 4
收藏数 71
精华内容 28
关键字:

临界区命名