精华内容
下载资源
问答
  • 互斥锁与信号量

    2015-11-23 13:09:29
    互斥锁与信号量的区别在于:  信号是用于多线程同步。一个线程完成了某一个动作就通过信号告诉别的线程,别的线程再进行某些动作。  互斥锁是用于多线程互斥。一个线程占用了某一个资源,那么别的线程就无法访问,...

    互斥锁与信号量的区别在于:
     信号是用于多线程同步。一个线程完成了某一个动作就通过信号告诉别的线程,别的线程再进行某些动作。
     互斥锁是用于多线程互斥。一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程离开,其他的线程才开始可以利用这个资源。互斥锁只能由加锁的线程解锁。
     条件变量定时等待和广播,用来唤醒阻塞在此条件变量上的所有线程。

    获得信号量服务为无条件挂起、时间间隙挂起、无挂起提供配置。一个试图获得当前计数值为零信号量的任务可以被挂起。当释放信号量请求发生时,任务恢复是可能的。多任务可以挂起,试图获得一个信号量。依靠信号量创建方式,任务既可以 FIFO 顺序也可以优先级顺序挂起。如果信号量支持 FIFO 挂起,任务按照它们试图获得信号量的顺序恢复。另外,如果信号量支持优先级挂起,任务从高优先级到低优先级顺序恢复。

    展开全文
  • 主要介绍了Python的互斥锁与信号量详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • C++ 多线程资源互斥锁与信号量 #include "windows.h" #include "process.h" #include "stdio.h" #include "stdlib.h" #include "winuser.h" //创建信号量 HANDLE signl = 0; //创建锁 CRITICAL_SECTION section; ...

    C++  多线程资源互斥锁与信号量

    #include "windows.h"
    #include "process.h"
    #include "stdio.h"
    #include "stdlib.h"
    #include "winuser.h"
    //创建信号量
    HANDLE signl = 0;
    //创建锁
    CRITICAL_SECTION section;
    
    //资源互斥锁
    unsigned _stdcall threadPool(VOID* e) {
    	//加锁
    	EnterCriticalSection(&section);
    	for (size_t i = 0; i < 16; i++) {
    		//SendMessage((HWND)0x00C60090, CB_SHOWDROPDOWN, 1, 0);
    		//向窗口发送信息
    		SendMessage((HWND)e,WM_PASTE, 0,0);
    		//PostMessage((HWND)0x00C60090,WM_PASTE, NULL, NULL);
    	};
    	//释放锁
    	LeaveCriticalSection(&section);
    	return 0;
    	
    };
    
    //信号量
    unsigned _stdcall SignlThreadPool(VOID* e) {
    	printf("%d等待中...!\n", &e);
    	//等待信号量
    	WaitForSingleObject(signl, INFINITE);
    	printf("%d启动了!\n", &e);
    	for (size_t i = 0; i < 16; i++) {
    		//SendMessage((HWND)0x00C60090, CB_SHOWDROPDOWN, 1, 0);
    		PostMessage((HWND)e, WM_PASTE, 0, 0);
    		Sleep(100);
    		//PostMessage((HWND)0x00C60090,WM_PASTE, NULL, NULL);
    	};
    	return 0;
    
    };
    //主窗口
    int main(int argc,TCHAR* argv[]) {
    	HWND hnd[4];
    	hnd[0] = (HWND)0x00C60090;
    	hnd[1] = (HWND)0x0034071E;
    	hnd[2] = (HWND)0x004A084C;
    	hnd[3] = (HWND)0x007E03C0;
    	//初始化资源互斥锁
    	InitializeCriticalSection(&section);
    	//创建信号量
    	signl = CreateEvent(NULL, TRUE, FALSE, NULL);
    	//
    	HANDLE hndle[4];
    	//循环创建线程
    	for (size_t i = 0; i < 4; i++) {
    		//hndle[i] = (HANDLE)_beginthreadex(NULL, NULL, threadPool, hnd[i], NULL, 0);
    		//获取创建的线程
    		hndle[i]=(HANDLE)_beginthreadex(NULL, NULL, SignlThreadPool, hnd[i], NULL, 0);
    	};
    	//休眠3秒
    	Sleep(3000);
    	//打开信号量
    	SetEvent(signl);
    	//等待线程执行完毕
    	for (size_t i = 0; i < 4; i++) {
    		WaitForSingleObject(hndle[i],INFINITE);
    	};
    	//删除资源互斥锁
    	DeleteCriticalSection(&section);
    	return 0;
    };

     

    展开全文
  • 互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候...

    “信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在 哪里)。而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候锁和信号量会同时使用的”

    也就是说,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务 并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。而线程互斥量则是“锁住某一资源”的概念,在锁定期间内,其他线程无法对被保护的数据进 行操作。在有些情况下两者可以互换。

    两者之间的区别:

    作用域

    信号量: 进程间或线程间(linux仅线程间的无名信号量pthread semaphore)

    互斥锁: 线程间

    上锁时

    信号量: 只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减一。若value值不大于0,则sem_wait使得线程阻塞,直到sem_post释放后value值加一,但是sem_wait返回之前还是会将此value值减一

    互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源

    以下是信号灯(量)的一些概念:

    信号灯与互斥锁和条件变量的主要不同在于”灯”的概念,灯亮则意味着资源可用,灯灭则意味着不可用。如果说后两中同步方式侧重于”等待”操作,即资 源不可用的话,信号灯机制则侧重于点灯,即告知资源可用;

    没有等待线程的解锁或激发条件都是没有意义的,而没有等待灯亮的线程的点灯操作则有效,且能保持 灯亮状态。当然,这样的操作原语也意味着更多的开销。

    信号灯的应用除了灯亮/灯灭这种二元灯以外,也可以采用大于1的灯数,以表示资源数大于1,这时可以称之为多元灯。

    1. 创建和 注销

    POSIX信号灯标准定义了有名信号灯和无名信号灯两种,但LinuxThreads的实现仅有无名灯,同时有名灯除了总是可用于多进程之间以外,在使用上与无名灯并没有很大的区别,因此下面仅就无名灯进行讨论。

    int sem_init(sem_t *sem, int pshared, unsigned int value)

    这是创建信号灯的API,其中value为信号灯的初值,pshared表示是否为多进程共享而不仅仅是用于一个进程。LinuxThreads没有实现 多进程共享信号灯,因此所有非0值的pshared输入都将使sem_init()返回-1,且置errno为ENOSYS。初始化好的信号灯由sem变 量表征,用于以下点灯、灭灯操作。

    int sem_destroy(sem_t * sem)

    被注销的信号灯sem要求已没有线程在等待该信号灯,否则返回-1,且置errno为EBUSY。除此之外,LinuxThreads的信号灯 注销函数不做其他动作。

    sem_destroy destroys a semaphore object, freeing the resources it  might  hold.  No  threads  should  be  waiting  on  the

    semaphore  at  the  time  sem_destroy  is  called.  In  the  LinuxThreads implementation, no resources are associated with

    semaphore objects, thus sem_destroy actually does nothing except checking that no thread is waiting on the semaphore.

    2. 点灯和灭灯

    int sem_post(sem_t * sem)

    点灯操作将信号灯值原子地加1,表示增加一个可访问的资源。

    int sem_wait(sem_t * sem)

    int sem_trywait(sem_t * sem)

    sem_wait()为等待灯亮操作,等待灯亮(信号灯值大于0),然后将信号灯原子地减1,并返回。sem_trywait()为sem_wait()的非阻塞版,如果信号灯计数大于0,则原子地减1并返回0,否则立即返回-1,errno置为EAGAIN。

    3. 获取灯值

    int sem_getvalue(sem_t * sem, int * sval)

    读取sem中的灯计数,存于*sval中,并返回0。

    4. 其他

    sem_wait()被实现为取消点。(取消点事什么意思???)

    sem_wait is a cancellation point.取消点的含义:

    当用pthread_cancel()一个线程时,这个要求会被pending起来,当被cancel的线程走到下一个cancellation point时,线程才会被真正cancel掉。

    而且在支持原子”比较且交换CAS”指令的体系结构上,sem_post()是唯一能用于异步信号处理函数的POSIX异步信号 安全的API。

    On processors supporting atomic compare-and-swap (Intel 486, Pentium and later, Alpha, PowerPC, MIPS  II,  Motorola  68k),

    the  sem_post function is async-signal safe and can therefore be called from signal handlers. This is the only thread syn-

    chronization function provided by POSIX threads that is async-signal safe.

    On the Intel 386 and the Sparc, the current LinuxThreads implementation of sem_post is not async-signal safe  by  lack  of

    the required atomic operations.

    互斥量(Mutex)

    互斥量表现互斥现象的数据结构,也被当作二元信号灯。一个互斥基本上是一个多任务敏感的二元信号,它能用作同步多任务的行为,它常用作保护从中断来的临界段代码并且在共享同步使用的资源。

    85d17528911abfa9cebfe82aaa9d49fb.gif

    Mutex本质上说就是一把锁,提供对资源的独占访问,所以Mutex主要的作用是用于互斥。Mutex对象的值,只有0和1两个值。这两个值也分别代表了Mutex的两种状态。值为0, 表示锁定状态,当前对象被锁定,用户进程/线程如果试图Lock临界资源,则进入排队等待;值为1,表示空闲状态,当前对象为空闲,用户进程/线程可以Lock临界资源,之后Mutex值减1变为0。

    Mutex可以被抽象为四个操作:

    - 创建 Create

    - 加锁 Lock

    - 解锁 Unlock

    - 销毁 Destroy

    Mutex被创建时可以有初始值,表示Mutex被创建后,是锁定状态还是空闲状态。在同一个线程中,为了防止死锁,系统不允许连续两次对Mutex加锁(系统一般会在第二次调用立刻返回)。也就是说,加锁和解锁这两个对应的操作,需要在同一个线程中完成。

    不同操作系统中提供的Mutex函数:

    动作\系统

    Win32

    Linyx

    Solaris

    创建

    CreateMutex

    pthread_mutex_init

    mutex_init

    加锁

    WaitForSingleObject

    pthread_mutex_lock

    mutex_lock

    解锁

    ReleaseMutex

    pthread_mutex_unlock

    mutex_unlock

    销毁

    CloseHandle

    pthread_mutex_destroy

    mutex_destroy

    信号量

    信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。

    信号量可以分为几类:

    ² 二进制信号量(binary semaphore):只允许信号量取0或1值,其同时只能被一个线程获取。

    ² 整型信号量(integer semaphore):信号量取值是整数,它可以被多个线程同时获得,直到信号量的值变为0。

    ² 记录型信号量(record semaphore):每个信号量s除一个整数值value(计数)外,还有一个等待队列List,其中是阻塞在该信号量的各个线程的标识。当信号量被释放一个,值被加一后,系统自动从等待队列中唤醒一个等待中的线程,让其获得信号量,同时信号量再减一。

    信号量通过一个计数器控制对共享资源的访问,信号量的值是一个非负整数,所有通过它的线程都会将该整数减一。如果计数器大于0,则访问被允许,计数器减1;如果为0,则访问被禁止,所有试图通过它的线程都将处于等待状态。

    计数器计算的结果是允许访问共享资源的通行证。因此,为了访问共享资源,线程必须从信号量得到通行证, 如果该信号量的计数大于0,则此线程获得一个通行证,这将导致信号量的计数递减,否则,此线程将阻塞直到获得一个通行证为止。当此线程不再需要访问共享资源时,它释放该通行证,这导致信号量的计数递增,如果另一个线程等待通行证,则那个线程将在那时获得通行证。

    Semaphore可以被抽象为五个操作:

    - 创建 Create

    - 等待 Wait:

    线程等待信号量,如果值大于0,则获得,值减一;如果只等于0,则一直线程进入睡眠状态,知道信号量值大于0或者超时。

    -释放 Post

    执行释放信号量,则值加一;如果此时有正在等待的线程,则唤醒该线程。

    -试图等待 TryWait

    如果调用TryWait,线程并不真正的去获得信号量,还是检查信号量是否能够被获得,如果信号量值大于0,则TryWait返回成功;否则返回失败。

    -销毁 Destroy

    信号量,是可以用来保护两个或多个关键代码段,这些关键代码段不能并发调用。在进入一个关键代码段之前,线程必须获取一个信号量。如果关键代码段中没有任何线程,那么线程会立即进入该框图中的那个部分。一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。

    动作\系统

    Win32

    POSIX

    创建

    CreateSemaphore

    sem_init

    等待

    WaitForSingleObject

    sem _wait

    释放

    ReleaseMutex

    sem _post

    试图等待

    WaitForSingleObject

    sem _trywait

    销毁

    CloseHandle

    sem_destroy

    互斥量和信号量的区别

    1. 互斥量用于线程的互斥,信号量用于线程的同步。

    这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。

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

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

    2. 互斥量值只能为0/1,信号量值可以为非负整数。

    也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。

    3. 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。

    展开全文
  • 并发锁多个线程共享数据的时候,如果数据不进行保护,那么可能出现数据不一致现象,使用锁,信号量、条件锁互斥锁1. 互斥锁,是使用一把锁把代码保护起来,以牺牲性能换取代码的安全性,那么Rlock后 必须要relase ...

    并发与锁

    多个线程共享数据的时候,如果数据不进行保护,那么可能出现数据不一致现象,使用锁,信号量、条件锁

    互斥锁

    1. 互斥锁,是使用一把锁把代码保护起来,以牺牲性能换取代码的安全性,那么Rlock后 必须要relase 解锁 不然将会失去多线程程序的优势

    2. 互斥锁的基本使用规则:

    import threading

    # 声明互斥锁

    lock=threading.Rlock();

    def handle(sid):# 功能实现代码

    lock.acquire() #加锁

    # writer codeing

    lock.relase() #释放锁

    信号量:

    1. 调用relarse()信号量会+1 调用 acquire() 信号量会-1

    可以理解为对于临界资源的使用,以及进入临界区的判断条件

    2. semphore() :当调用relarse()函数的时候 单纯+1 不会检查信号量的上限情况。 初始参数为0

    3. boudedsemphore():边界信号量 当调用relarse() 会+1 , 并且会检查信号量的上限情况。不允许超过上限

    使用budedsemaphore时候不允许设置初始为0,将会抛出异常

    至少设置为1 ,如consumer product 时候应该在外设置一个变量,启动时候对变量做判断,决定使不使用acquier

    4. 信号量的基本使用代码:

    # 声明信号量:

    sema=threading.Semaphore(0); #无上限检查

    sema=threading.BuderedSeamphore(1) #有上限检查设置

    5

    apple=1

    def consumner():

    seam.acquire(); # ‐1

    9

    if apple==1:

    pass

    else: sema2.release();#+ 1

    def product():

    seam.relarse(); # +1

    if apple==1:

    pass

    else:

    print("消费:",apple);

    全部的代码:

    # -*- coding: utf-8 -*-

    """

    Created on Mon Sep 9 21:49:30 2019

    @author: DGW-PC

    """

    # 信号量解决生产者消费者问题

    import random;

    import threading;

    import time;

    # 声明信号量

    sema=threading.Semaphore(0);# 必须写参数 0 表示可以使用数

    sema2=threading.BoundedSemaphore(1);

    apple=1;

    def product():#生产者

    global apple;

    apple=random.randint(1,100);

    time.sleep(3);

    print("生成苹果:",apple);

    #sema2.release(); # +1

    if apple==1:

    pass

    else: sema2.release();#+ 1

    def consumer():

    print("等待");

    sema2.acquire();# -1

    if apple==1:

    pass

    else:

    print("消费:",apple);

    threads=[];

    for i in range(1,3):

    t1=threading.Thread(target=consumer);

    t2=threading.Thread(target=product);

    t1.start();

    t2.start();

    threads.append(t1);

    threads.append(t2);

    for x in threads:

    x.join();

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

    时间: 2019-09-11

    展开全文
  • 并发锁多个线程共享数据的时候,如果数据不进行保护,那么可能出现数据不一致现象,使用锁,信号量、条件锁互斥锁1. 互斥锁,是使用一把锁把代码保护起来,以牺牲性能换取代码的安全性,那么Rlock后 必须要relase ...
  • 多个线程共享数据的时候,如果数据不进行保护,那么可能出现数据不一致现象,使用锁,信号量、条件锁 b. c.互斥锁1. 互斥锁,是使用一把锁把代码保护起来,以牺牲性能换取代码的安全性,那么Rlock后 必须要...
  • 驱动程序之字符设备_7_互斥锁与信号量 上一篇文章的要求,除了原子操作,也可以使用本文的互斥锁代替实现 互斥锁的作用是:保证共享数据操作的完整性,每个对象都对应于一个可称为&amp;amp;amp;amp;quot; 互斥...
  • 互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候...
  • 一、互斥与同步 互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。 同步是指在互斥的基础上(大多数情况),通过其它机制实现访问...
  • 互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候...
  • 关于互斥锁与信号量

    2013-11-07 17:24:35
    在对于某个共用资源的访问的问题上,经常使用互斥锁信号量来做互斥、同步的工作。所谓互斥锁,顾名思义,其功能体现在互斥上,而它实现互斥的过程就像“锁”一样,在某一个访问者在使用该共用资源时,这个使用者对...
  • 线程的同步互斥 2019-12-07: (POSIX中2种线程同步机制) ...信号量:更适合用于同时可用的资源 为多个的情况; 互斥锁:针对线程 互斥锁是用一种简单的加锁方法来控制对共享资源的原子操...
  • 互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候...
  • 多线程中互斥锁与信号量的区别

    千次阅读 2018-07-25 14:55:14
    在使用多线程的过程中对于互斥锁信号量使用比较迷糊,不知道二者有什么区别,都能保证线程互斥,现做以下说明: “信号量是一个线程完成了某一任务就通过信号量告诉别的线程,别的线程再进行某些动作。而互斥锁是...
  • 互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候...
  • 互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候...
  • 线程在unix下,被称为轻级的进程,线程虽然不是进程,但却可以看作是unix进程的表亲,同一进程中的多条线程将共享该进程中的全部资源,如虚拟地址空间,文件描述服,和信号处理等等。但同一进程中的多个线程有各自...
  • 互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,502
精华内容 600
关键字:

互斥锁与信号量