barriers / 阅读 / 详情

扩展Delphi的线程同步对象

2023-08-25 01:32:00
TAG: ph el lp del delphi
共1条回复
西柚不是西游

   在编写多线程应用程序时 最重要的是控制好线程间的同步资源访问 以保证线程的安全运行 Win API提供了一组同步对象 如 信号灯(Semaphore) 互斥(Mutex) 临界区(CriticalSection)和事件(Event)等 用来解决这个问题

  Delphi分别将事件对象和临界区对象封装为Tevent对象和TcritialSection对象 使得这两个对象的使用简单且方便 但是如果在Delphi程序中要使用信号灯或互斥等对象就必须借助于复杂的Win API函数 这对那些不熟悉Win API函数的编程人员来说很不方便 因此 笔者用Delphi构造了两个类 对信号灯和互斥对象进行了封装(分别为TSemaphore和TMutex) 希望对广大Delphi编程人员有所帮助

   一 类的构造   我们先对Win API的信号灯对象和互斥对象进行抽象 构造一个父类THandleObjectEx 然后由这个父类派生出两个子类Tsemphore和Tmutex

  类的源代码如下

  unit SyncobjsEx;

  interface

  uses Windows Messages SysUtils Classes Syncobjs;

  type

   THandleObjectEx = class(THandleObject)

  // THandleObjectEx为互斥类和信号灯类的父类

   protected

   FHandle: THandle;

   FLastError: Integer;

   public

   destructor Destroy; override;

   procedure Release;

   override;

   function WaitFor(Timeout: DWORD): aitResult;

   property LastError:Integer read FLastError;

   property Handle: THandle read FHandle;

   end;

   TMutex = class(THandleObjectEx)//互斥类

   public

   constructor Create(MutexAttributes: PSecurityAttributes;

   InitialOwner: Boolean;const Name:string);

   procedure Release;

   override;

   end;

   TSemaphore = class(THandleObjectEx)

  //信号灯类

  public

  constructor Create(SemaphoreAttributes: PSecurityAttributes;

  InitialCount:Integer;

  MaximumCount: integer;

  const Name: string);

  procedure Release(ReleaseCount: Integer= ;PreviousCount:Pointer=nil)

  overload;

  end;

  implementation

  { THandleObjectEx }//父类的实现

  destructor THandleObjectEx Destroy;

  begin

  Windows CloseHandle(FHandle);

  inherited Destroy;

  end;

  procedure THandleObjectEx Release;

  begin

  end;

  function THandleObjectEx WaitFor(Timeout: DWORD): aitResult;

  //等待函数 参数为等待时间

  begin

  case WaitForSingleObject(Handle Timeout) of

  WAIT_ABANDONED: Result := wrAbandoned;

  //无信号

  WAIT_OBJECT_ : Result := wrSignaled;

  //有信号

  WAIT_TIMEOUT: Result := wrTimeout;//超时

  WAIT_FAILED://失败

   begin

   Result := wrError;

   FLastError := GetLastError;

   end;

   else

   Result := wrError;

   end;

   end;

  { TSemaphore }//信号灯类的实现

  constructor TSemaphore Create(SemaphoreAttributes: PSecurityAttributes;

  InitialCount MaximumCount: integer; const Name: string);//信号灯类的构造函数

  begin

  FHandle := CreateSemaphore

  (SemaphoreAttributes InitialCount MaximumCount PChar(Name));

  //四个参数分别为 安全属性 初始信号灯计数 最大信号灯计数 信号灯名字

  end;

  procedure TSemaphore Release(ReleaseCount: Integer= ; PreviousCount:Pointer=nil);

  //信号灯类的Release方法 每执行一次按指定量增加信号灯计数

  begin

  Windows ReleaseSemaphore(FHandle ReleaseCount PreviousCount);

  end;

  { TMutex }//互斥类的实现

  constructor TMutex Create(MutexAttributes: PSecurityAttributes;

  InitialOwner: Boolean; const Name: string);

  //互斥类的构造函数

  begin

  FHandle := CreateMutex(MutexAttributes InitialOwner PChar(Name));

  end;

  procedure TMutex Release;//互斥类的Release方法 用来释放对互斥对象的所有权

  begin

  Windows ReleaseMutex(FHandle);

  end;

  end;

   二 信号灯对象与互斥对象的使用    信号灯对象

  信号灯对象维持一个从 到指定最大值之间的数 在其计数大于 时是有信号的 而在其计数为 时是无信号的 信号灯对象可用来限制对共享资源进行访问的线程数量 例如应用程序可使用信号灯对象来限制它建立的窗口数量

  用类的Create方法来建立信号灯对象 在调用该方法时 可以指定对象的初始计数和最大计数 该方法有四个参数 依次为 安全属性 初始计数 最大计数和对象名字(以便别的进程的线程可打开指定名字的信号灯句柄) 如

  Semaphore := TSemaphore Create(nil );

  一般把信号灯的初始计数设置成最大值 每次当信号灯有信号并等待函数返回时 信号灯计数就会减 而通过调用对象的Release方法可按指定量增加信号灯的计数(默认为加 ) 计数值越小就表明访问共享资源的程序越多 如 Semaphore Release( nil); 其中第一个参数为增加的信号灯数量 第二个参数为执行该方法之前的信号灯数量   信号灯用法举例

  if wrSignaled = Semaphore WaitFor( ) then//若信号灯是有信号的

  begin

   //打开另一个窗口

  end

   Semaphore Release()

  在线程建立窗口之前 它使用WaitFor函数确定信号灯的当前计数是否允许建立新的窗口 等待时间设为 秒

   互斥对象

  Mutex对象的状态在它不被任何线程拥有时是有信号的 而当它被拥有时则是无信号的 Mutex对象很适合用来协调多个线程对共享资源的互斥访问(mutually exclusive) 例如 有几个线程共享对数据库的访问时 线程可以使用Mutex对象 一次只允许一个线程向数据库写入

  用类的Create方法建立Mutex 对象 在建立Mutex 时 可以为对象起个名字 这样其他进程中的线程可以打开指定名字的Mutex对象句柄 例如

  Mutex := TMutex Create(nil False );

  在完成对共享资源的访问后 可以调用Release方法来释放Mutex 以便让别的线程能访问共享资源 如果线程终止而不释放Mutex 则认为该Mutex被废弃

  互斥对象用法举例如下

  if wrSignaled = Mutex WaitFor( ) then//若获得互斥对象的拥有权

   begin

   try

   //往数据库写入

   finally

  Mutex Release;//释放对互斥对象的拥有权

   end;

   end;

lishixinzhi/Article/program/Delphi/201311/8521

相关推荐

深入理解mutex工作机制

可以认为是一种更加轻量级的latch, 两者的区别在于:mutex是内存结构本身所包含,随着内存的分配而分配、销毁而销毁,latch是一种独立的内存结构。基于这个特性,mutex保护的内存结构更细粒度,并发性、支持性要好于latch. 与shared latch一样可使mutex用cas模式申请latch. 因此也可以把mutex当成一种shared latch, 只是其粒度更细,更加轻量级。mutex采用spin+FIRO策略,而shared latch采用spin+FIFO策略。更多详细关于mutex的原理可以参见: 从10.2.0.2版本开始,oracle的mutex机制逐步替代了传统的library cache的一些机制。 #### 10.2.0.5 #### #### 11.2.0.4 #### 不同版本中,对于library cache的latch变化较大,特别是从Oracle 10gR2(10.2.0.2)开始,引入了mutex来替代cursor的latch. 在该版本上通过隐含参数_kks_use_mutex_pin的调整可以限制是否使用Mutex机制来实现Cursor Pin. mutex与latch的对应关系如下: 以下参数在11.2.0.2以上才有 由于mutex采用了传统的spin+sleep机制而不是latch的spin+post机制,所以sleep time的设置对于mutex性能具有重要地位,一般来说由于mutex的冲突远比latch要小,所以合适的yield和更小的sleep选择是恰当的。一般情况不需要改动,默认都是1ms. 不同模式的比较可以参考: 不包含sleep, 只在简单yield之后进行不断的mutex spin. 显然,在冲突不发生的情况下会有最好的性能,但是在有冲突的时候可能会消耗很高的CPU资源。 对10g模式的一种修正,增加了sleep部分以降低CPU消耗,sleep时间收到参数_first_spare_parameter的控制 在Solaris SPARC 10.2.0.4这个参数是_second_spare_parameter. mutex的spin次数受mutex_spin_count控制,默认为255. 该参数可以动态修改。 某些时候,该值可能需要适当增大来获取更好的性能。设置方法可参考latch的spin count设置方法。v$mutex_sleep_history视图包含相关的gets和sleep信息。 关于mutex_spin_conut设置对mutex响应性能的影响可参考:
2023-08-18 23:01:171

mutex=1表示什么意思

mutex为互斥信号量,其初值为1,取值范围为(-1, 0, 1)。 当mutex=1时,表示两个进程皆未进入需要互斥的临界区;当mutex=0时,表示有一个进程进入临界区运行,另外-一个必须等待,挂入阻塞队列;当mutex=-1时,表示有一个进程正在临界区运行,另外一个进程因等待而阻塞在信号量队列中,需要被当前已在临界区运行的进程退出时唤醒。
2023-08-18 23:01:271

mutex的英文音标是什么,怎么发音? 怎么发音呢?

mutex 互斥(体) /mjuteks/
2023-08-18 23:01:491

信号量vs互斥锁(Semaphore vs Mutex)

信号量是一个被线程共享的非负变量。信号量是一个发信号的机制。一个等待一个信号量的线程可以被其他线程通知(signal)。这个机制通过 wait 和 signal 两个原子操作(atomic operations)来实现进程同步。 一个信号量要么允许访问资源,要么不允许访问资源。二者只能选其一。而具体是哪一种,则要看设置。 详情可参考《 信号量:二进位信号量和计数信号量 》这篇文章。 互斥锁其实是一个对象。Mutex的全称是Mutual Exclusion Object,也就是互斥锁是一个互斥对象。它是一种特殊的二进位信号量(binary semaphore),用来控制访问共享区域资源。它包括一个优先级继承机制,以避免扩展的优先级反转问题。它允许当前优先级较高的任务在阻塞状态下维持的时间尽可能的少。然而,优先级继承并不能完全避免优先级反转,而只会最小化其影响。 对于单个缓冲区(single buffer),我们可以将4kb缓冲区分成四个1kb缓冲区。信号量可以与这四个缓冲区相关联。这允许用户和生产者同时处理不同的缓冲区。 互斥锁用于提供互斥,它使得拥有钥匙(key or mutex)的生产者才能访问资源。只要生产者占用了缓冲区(buffer),用户必须等待,反之亦然。在互斥锁的机制中,整块缓冲区始终只能提供给一个线程访问。 下面列举信号量的优点: 下面列举互斥锁的优点: 下面列举信号量的缺点: 下面列举互斥锁的缺点:
2023-08-18 23:01:581

操作系统消费者进程中,wait(full)和wait(mutex)顺序不能颠倒?

1、首先,缓冲池为空,就没有产品。full=0,这里还要强调,mutex是全局互斥信号量。2、这个时候先来了个消费者,他的程序如下:wait(mutex);挂起了,并且占用了mutex,wait(full);不管来多少消费者,都在mutex队列排队,死锁了。3、这个时候生产者的程序wait(empty);可行wait(mutex)也挂起了, 因为mutex给消费者用了,就是说缓冲区给消费者占用了啦!生产者和消费者都等待了,系统死锁了。
2023-08-18 23:02:081

Mutex和信号量的区别

Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个,一般的用法是用于串行化对临界区代码的访问,保证这段代码不会被并行的运行。Semaphore是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为binary semaphore,一般的用法是,用于限制对于某一资源的同时访问。在有的系统中Binary semaphore与Mutex是没有差异的
2023-08-18 23:02:162

计算机操作系统互斥信号量mutex怎么解释

一般mutex为1,0,-1,……,1表示程序可以进入临界区,可以执行p操作,但执行后要令1变为0
2023-08-18 23:02:271

Linux mutex为什么不能用在中断函数

Linux mutex不能用在中断函数原因:Backtrace来看,应该是i2c_transfer中调用mutex_lock导致schedule调用。pthread_mutex_lock(&qlock);表示尝试去把qlock上锁,它会先判断qlock是否已经上锁,如果已经上锁这个线程就会停在这一步直到其他线程把锁解开。它才继续运行。所以代码中要么是线程1先执行完后执行线程2,要么就是线程2先执行,再执行线程1.而线程3一开始就执行了。中断函数防止方法:要防止中断冲突,其实就是要知道什么设备容易产生中断冲突,只要知道了这点,在使用这些设备时稍微注意一下就可以了。下面我列出一些容易冲突的设备,希望对读者有用。1、声卡:一些早期的ISA型声卡,系统很有可能不认,就需要用户手动设置(一般为5)。2、内置调制解调器和鼠标:一般鼠标用COM1,内置调制解调器使用COM2的中断(一般为3),这时要注意此时COM2上不应有其它设备。
2023-08-18 23:02:341

mutex的英文音标是什么,怎么发音?

mutex 互斥(体) /mjuteks/
2023-08-18 23:03:003

windows使用什么对象使多线程之间对资源互斥

互斥对象的使用和Event的使用基本是一致的。区别在于,Mutex被称为全局互斥对象,不仅可以在多线程中使用,甚至还可以在多进程中使用。Mutex是一个命名对象,所有用同一个名字创建的Mutex都会被视为同一个对象。 无论是Mutex还是Event都有同步和互斥两种用法。很多资源因为本身的特性,要求同时只能有一个线程访问,比如vector之类的数据结构,同时有两个线程做插入操作,数据就会出错;代码也是一样,有一些代码本身是不允许在多线程中间同时进入的。这时候就可以用Mutex或者Event来进行互斥。 具体方法是创建一个初值为True(Set)的AutoReset(ManualReset参数为FALSE)的Mutex或者Event,然后每次要访问对应的资源的时候首先WaitForSingleObject,成功Wait到之后,Event或者Mutex会变成False(Unset)的状态,其他线程就无法进入;等到使用结束之后,再SetEvent使Mutex或者Event恢复Set的状态,让其他等待的线程进入。 CriticalSection之类的模块在内部也是使用了Event或者Mutex来完成互斥的。注意需要对每一个互斥的资源或代码使用一个独立的Mutex或者Event。
2023-08-18 23:03:091

在生产者和消费者问题中,如果将P操作位置互换,会产生什么结果

看了很多回答,还是一头雾水,主要是文字描述太多,不够简练,下面让我来答。P操作互换可能会导致死锁,V操作不会导致死锁。因为操作系统不会去通过一大堆的文字描述来厘清到底现在要不要死锁。而是通过各个信号量的值来判断(几乎无需用脑),那么先定规矩:第一条:互斥信号量mutex初值为1,若为0表示有一个进程正在进入临界区,若小于0则说明可能不止一个进程和你一样(即需要使用该资源)。简单来说,只有mutex为1,你才可以使用该资源。第二条:满缓冲区信号量full初值为0,且大于0时,为几就表示几个缓冲区已满。(当然不可能为负)。第三条:空缓冲区信号量empty初值为n,且大于0时,为几就表示几个缓冲区为空。(当然不可能为负)。那么正常的是p(full);p(mutex);如果互换,变为p(mutex);p(full);当执行完p(mutex)后,mutex值为0,此时对缓冲区就不能操作了;但是如果先执行p(full),那么只要有1个缓冲区,都可以继续执行(不管是否为满,大多数的回答都举例为满),因为full与mutex的规则不同,mutex可以为负,但full不可能为负(我之前没想通就是因为这点)。对于V操作,正常为v(mutex);v(empty);如果互换,则v(empty);v(mutex);看到没,V操作是加1 ,那么不管顺序怎么样,都可以实现加1,不影响缓冲区互斥。看就这么简单,二年级数学的水平都可以理解,准确把握规则是前提。
2023-08-18 23:03:203

请解释多线程事件中lock、monitor以及mutex机制的含义与区别

总线程锁定、数据监控 和 多用户终端执行程序
2023-08-18 23:03:292

Linux中 条件变量为什么要用互斥锁来保护?

看看哲学家就餐问题之类的....
2023-08-18 23:04:063

怎么样定义freertos的mutex的数组

1、将字符串数组定义为全局数组;2、线程A:pthread_mutex_lock(mutex);接收输入;写入数组;pthread_mutex_unlock(mutex);3、线程B:pthread_mutex_lock(mutex);显示数组内容;清空数组;pthread_mutex_unlock(mutex);
2023-08-18 23:05:481

linux mutex有超时机制吗

从Backtrace来看,应该是i2c_transfer中调用mutex_lock导致schedule调用而产生进程调度,导致死机.而在中断上下文,这种情况是绝对不允许发生的.换句话说是不允许 睡眠的,不允许进程调度. 你可以把mutex_lock注释掉再试试.
2023-08-18 23:05:561

关于c#中Mutex的问题

你这种方式是比较合理的方式,lpClassName 是要查的,而且也是固定的。如果你不用 lpClassName ,可以用程序的标题IntPtr hWnd = FindWindow(null, "标题"); ShowWindowAsync(hWnd, 1); SetForegroundWindow(hWnd);
2023-08-18 23:06:151

(C语言中)互斥锁的死锁问题

如果你将mutex_c换成mutex_p,则不会死锁,因为,你第一个线程锁上后,切换到第二个线程,因为mutex_p未释放,第二个线程无法获取mutex_p,进入等待状态,此时OS将再次调度第一个线程,直到第一个线程释放mutex_p之后,第二个线程才会被激活,然后调试第二线程,获取mutex_p.使用OS提供的互斥量来保护公共资源还是比较安全的,但如果用二值信号量的话,就可能会有优先级反转的情况.
2023-08-18 23:06:231

当线程结束后会自动释放mutex么

问题出在CreateMutex()函数调用的参数上。把第二个参数改为true或者TRUE就行了。为什么会出现这个问题?第二个参数指定这个互斥量是否立即被这个进程使用,如果指定为true,则立即生效,否则无效的.呵呵,这个问题挺隐晦的(以后得小心了)!你的线程里不要直接使用在main()中定义的循环变量,这会出问题的,也就是临界区问题!你问的问题线程会自动释放互斥量吗?当然不会的,只有当进程退出后,未被释放的互斥量会被操作系统释放的。我提个小建议,阁下应该改改你的编码风格了,你目前使用的编码风格不大漂亮!呵呵下面是改过的源代码(加了一些注释,你可以看看).. 有问题的话追问! #include <iostream>#include <Windows.h>#include <stdio.h>#include <stdlib.h>using namespace std; #define Thread_Num 3 //C++中尽量不要用宏,应该使用const int thread_num = 3; /*变量名对象名一般全小写,宏的名字一般用全部大写*/HANDLE hMutex;DWORD WINAPI ThreadFun(LPVOID); int main() { int id; HANDLE handle[Thread_Num]; hMutex=CreateMutex(NULL,TRUE,NULL); for(int i=0;i<Thread_Num;i++) { /*在线程中不要直接使用i*/ handle[i]=CreateThread(NULL,0,ThreadFun,(LPVOID)i,0,(LPDWORD)&id); if(handle[i]) { cout<<"线程"<<id<<"被创建"<<endl; } } WaitForMultipleObjects(Thread_Num,handle,TRUE,INFINITE); system("pause"); return EXIT_SUCCESS; //这一行可以不要的,编译器会自动加上去的}DWORD WINAPI ThreadFun(LPVOID lp) { WORD result= WaitForSingleObject(hMutex,INFINITE); cout<<(int)lp<<endl; WaitForSingleObject(hMutex,INFINITE); return 0;}
2023-08-18 23:06:301

C++多线程mutex对象作为类的成员变量为何编译报错attempted to reference a deleted function?

这和mutex没直接关系,你只是触发对已经删除的函数的调用了。比如mutex的operator=
2023-08-18 23:06:381

数据库题 用P、V操作管理临界区时,把信号量mutex的初值设定为1。当mutex的等待队列中有

选D,需要释放资源
2023-08-18 23:06:485

entermutex和leavemutex是啥意思

enter mutex进入互斥leave mutex离开互斥
2023-08-18 23:07:041

Linux下线程同步的几种方法

Linux系统中,实现线程同步的方式大致分为六种,包括:互斥锁、自旋锁、信号量、条件变量、读写锁、屏障。其最常用的线程同步方式就是互斥锁、自旋锁、信号量。1、互斥锁互斥锁本质就是一个特殊的全局变量,拥有lock和unlock两种状态,unlock的互斥锁可以由某个线程获得,当互斥锁由某个线程持有后,这个互斥锁会锁上变成lock状态,此后只有该线程有权力打开该锁,其他想要获得该互斥锁的线程都会阻塞,直到互斥锁被解锁。互斥锁的类型:①普通锁:互斥锁默认类型。当一个线程对一个普通锁加锁以后,其余请求该锁的线程将形成一个等待队列,并在锁解锁后按照优先级获得它,这种锁类型保证了资源分配的公平性。一个线程如果对一个已经加锁的普通锁再次加锁,将引发死锁;对一个已经被其他线程加锁的普通锁解锁,或者对一个已经解锁的普通锁再次解锁,将导致不可预期的后果。②检错锁:一个线程如果对一个已经加锁的检错锁再次加锁,则加锁操作返回EDEADLK;对一个已经被其他线程加锁的检错锁解锁或者对一个已经解锁的检错锁再次解锁,则解锁操作返回EPERM。③嵌套锁:该锁允许一个线程在释放锁之前多次对它加锁而不发生死锁;其他线程要获得这个锁,则当前锁的拥有者必须执行多次解锁操作;对一个已经被其他线程加锁的嵌套锁解锁,或者对一个已经解锁的嵌套锁再次解锁,则解锁操作返回EPERM。④默认锁:一个线程如果对一个已经解锁的默认锁再次加锁,或者对一个已经被其他线程加锁的默认锁解锁,或者对一个解锁的默认锁解锁,将导致不可预期的后果;这种锁实现的时候可能被映射成上述三种锁之一。2、自旋锁自旋锁顾名思义就是一个死循环,不停的轮询,当一个线程未获得自旋锁时,不会像互斥锁一样进入阻塞休眠状态,而是不停的轮询获取锁,如果自旋锁能够很快被释放,那么性能就会很高,如果自旋锁长时间不能够被释放,甚至里面还有大量的IO阻塞,就会导致其他获取锁的线程一直空轮询,导致CPU使用率达到100%,特别CPU时间。3、信号量信号量是一个计数器,用于控制访问有限共享资源的线程数。
2023-08-18 23:07:152

linux下mutex包含的在哪个头文件

① 点击菜单上的新建; ② 设置一个名称,设置类型为 Linux,版本 Ubuntu(64 bit) 2 设置内存大小为2048 3 点击下一步 4 点击下一步 5 点击下一步 6 设置硬盘40G
2023-08-18 23:07:221

linux驱动里 mutex_lock(&amp;tty_mutex)有什么作用?

mutex_lock是用来保护资源。比如某一个变量,多个函数都会对该变量进行操作,为了保证在同一时间,只能有同一个函数对该变量的操作,需要对该变量进行加锁和解锁操作,用来防止不可预知的错误。多线程,多进程中更应该如此。希望对你有帮助!
2023-08-18 23:07:321

c++ std::mutex 锁

那就不调用啊,你的A函数已经加锁了。干嘛好调用AAA再加一次锁。而且互斥锁只能加锁一次,你的A里面加完锁,进入到AAA里面就就会导致AAA函数永远没办法获取到锁,从而阻塞在那里。
2023-08-18 23:07:391

C# 为什么两个线程不能同时等待一个Mutex 释放

http://www.codeproject.com/KB/threads/ThreadingDotNet.aspx
2023-08-18 23:07:582

请问c语言if(mutex==0)是表示什么意思

http://www.xfbbs.com/Book/jinghuawenzhai/VB_1/htmapi73.htm我也没有明白她写的是什么意思,但也许有用吧!
2023-08-18 23:08:093

将std::mutex放入std::map中

参考: c++ - Map of mutex c++11 - Stack Overflow std::mutex不好放进map的主要原因是: TL;DR: just use operator [] like std::map<std::string, std::mutex> map; map[filename]; Why do you need to use an std::unique_ptr in the first place? I had the same problem when I had to create an std::map of std::mutex objects. The issue is that std::mutex is neither copyable nor movable, so I needed to construct it "in place". I couldn"t just use emplace because it doesn"t work directly for default-constructed values. There is an option to use std::piecewise_construct like that: but it"s IMO complicated and less readable. My solution is much simpler - just use the operator[] - it will create the value using its default constructor and return a reference to it. Or it will just find and return a reference to the already existing item without creating a new one.
2023-08-18 23:08:161

互斥锁的属性对象

使用pthread_mutexattr_init(3C)可以将与互斥锁对象相关联的属性初始化为其缺省值。在执行过程中,线程系统会为每个属性对象分配存储空间。pthread_mutexattr_init 语法int pthread_mutexattr_init(pthread_mutexattr_t *mattr);#include <pthread.h>pthread_mutexattr_t mattr;int ret;/* initialize an attribute to default value */ret = pthread_mutexattr_init(&mattr);调用此函数时,pshared 属性的缺省值为 PTHREAD_PROCESS_PRIVATE。该值表示可以在进程内使用经过初始化的互斥锁。mattr 的类型为 opaque,其中包含一个由系统分配的属性对象。mattr 范围可能的值为 PTHREAD_PROCESS_PRIVATE 和 PTHREAD_PROCESS_SHARED。PTHREAD_PROCESS_PRIVATE 是缺省值。对于互斥锁属性对象,必须首先通过调用 pthread_mutexattr_destroy(3C) 将其销毁,才能重新初始化该对象。pthread_mutexattr_init()调用会导致分配类型为 opaque 的对象。如果未销毁该对象,则会导致内存泄漏。ENOMEM描述:内存不足,无法初始化互斥锁属性对象。
2023-08-18 23:08:231

《幕府将军2》打不开,咚的一声就黑屏,出现了:Mutex error 的界面

another instance of total war:shogun 2 is running please close this instance before attempting to run another instance 意思是:另一个幕府2全面战争的实例: 试图运行另一个实例之前,请关闭这个实例 出现了:Mutex error 的界面 原因是Mutex的错误 我个人来讲的话,是你电脑配置问题或你下载的游戏是坏的 幕府将军2配置的要求 处理器方面,建议采用四核处理器,主频保证在2.8GHz以上; 内存方面,建议保证3GB或者更高容量的内存; 显卡方面,建议GTX460或HD6850级别的产品。 所以楼主你的配置比起这个要求来是差了很远 官方配置: 最低配置: ·CPU:英特尔双核 2 GHz / 英特尔单核 2.6 GHz 或 等效AMD (支持 SSE2) ·内存:1GB (XP) / 2GB (Vista 或 Windows7) ·显卡:显存256 MB 支持DirectX 9.0c (SM3.0) ·硬盘:20 GB ·显示器:1024×768 分辨率 推荐配置: ·CPU:第二代英特尔酷睿 i5 / 等效AMD(i7比较好,有测试证明) ·内存:2GB (XP), 4GB (Vista 或 Windows7) ·显卡:AMD Radeon HD 5000 和 6000 或等效的支持DirectX 11的显卡 ·硬盘:20 GB ·显示器:1280×1024 分辨率 你自己看看吧不懂得你可以来Q我 QQ:1060669328
2023-08-18 23:08:371

操作系统中生产者消费者问题。消费者进程中,wait(full)和wait(mutex)顺序不能颠倒,能否详细说明为什么不

可能网上有很多说话。下面是我自己的看法。首先,缓冲池为空,就没有没有产品,;full=0,这里还要强调,mutex是全局互斥信号量。这个时候先来了个消费者,他的程序如下:wait(mutex);挂起了,并且占用了mutex,wait(full);……不管来多少消费者,都在mutex队列排队,死锁了。这个时候;生产者,的程序wait(empty);可行wait(mutex):也挂起了, 因为mutex给消费者用了,就是说缓冲区给消费者占用了啦!生产者和消费者都等待了,系统死锁了。希望你能明白我说的。
2023-08-18 23:08:472

互斥锁的示例

下面举例:在Posix Thread中定义有一套专门用于线程同步的mutex函数。1. 创建和销毁有两种方法创建互斥锁,静态方式和动态方式。POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER来静态初始化互斥锁,方法如下: pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; 在LinuxThreads实现中,pthread_mutex_t是一个结构,而PTHREAD_MUTEX_INITIALIZER则是一个结构常量。动态方式是采用pthread_mutex_init()函数来初始化互斥锁,API定义如下: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr) 其中mutexattr用于指定互斥锁属性(见下),如果为NULL则使用缺省属性。pthread_mutex_destroy ()用于注销一个互斥锁,API定义如下: int pthread_mutex_destroy(pthread_mutex_t *mutex) 销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。由于在Linux中,互斥锁并不占用任何资源,因此LinuxThreads中的 pthread_mutex_destroy()除了检查锁状态以外(锁定状态则返回EBUSY)没有其他动作。2. 互斥锁属性互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。当前(glibc2.2.3,linuxthreads0.9)有四个值可供选择:* PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。* PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。* PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。* PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。3.锁操作锁操作主要包括加锁pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁 pthread_mutex_trylock()三个,不论哪种类型的锁,都不可能被两个不同的线程同时得到,而必须等待解锁。对于普通锁和适应锁类型,解锁者可以是同进程内任何线程;而检错锁则必须由加锁者解锁才有效,否则返回EPERM;对于嵌套锁,文档和实现要求必须由加锁者解锁,但实验结果表明并没有这种限制,这个不同还没有得到解释。在同一进程中的线程,如果加锁后没有解锁,则任何其他线程都无法再获得锁。int pthread_mutex_lock(pthread_mutex_t *mutex)int pthread_mutex_unlock(pthread_mutex_t *mutex)int pthread_mutex_trylock(pthread_mutex_t *mutex)pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待。4. 其他POSIX 线程锁机制的Linux实现都不是取消点,因此,延迟取消类型的线程不会因收到取消信号而离开加锁等待。值得注意的是,如果线程在加锁后解锁前被取消,锁将永远保持锁定状态,因此如果在关键区段内有取消点存在,或者设置了异步取消类型,则必须在退出回调函数中解锁。这个锁机制同时也不是异步信号安全的,也就是说,不应该在信号处理过程中使用互斥锁,否则容易造成死锁。互斥锁属性使用互斥锁(互斥)可以使线程按顺序执行。通常,互斥锁通过确保一次只有一个线程执行代码的临界段来同步多个线程。互斥锁还可以保护单线程代码。要更改缺省的互斥锁属性,可以对属性对象进行声明和初始化。通常,互斥锁属性会设置在应用程序开头的某个位置,以便可以快速查找和轻松修改。表 4–1列出了用来处理互斥锁属性的函数。表 4–1 互斥锁属性例程 操作 相关函数说明 初始化互斥锁属性对象 pthread_mutexattr_init 语法 销毁互斥锁属性对象 pthread_mutexattr_destroy 语法 设置互斥锁范围 pthread_mutexattr_setpshared 语法 获取互斥锁范围 pthread_mutexattr_getpshared 语法 设置互斥锁的类型属性 pthread_mutexattr_settype 语法 获取互斥锁的类型属性 pthread_mutexattr_gettype 语法 设置互斥锁属性的协议 pthread_mutexattr_setprotocol 语法 获取互斥锁属性的协议 pthread_mutexattr_getprotocol 语法 设置互斥锁属性的优先级上限 pthread_mutexattr_setprioceiling 语法 获取互斥锁属性的优先级上限 pthread_mutexattr_getprioceiling 语法 设置互斥锁的优先级上限 pthread_mutex_setprioceiling 语法 获取互斥锁的优先级上限 pthread_mutex_getprioceiling 语法 设置互斥锁的强健属性 pthread_mutexattr_setrobust_np 语法 获取互斥锁的强健属性 pthread_mutexattr_getrobust_np 语法 表 4–2中显示了在定义互斥范围时 Solaris 线程和 POSIX 线程之间的差异。表 4–2 互斥锁范围比较 Solaris POSIX 定义 USYNC_PROCESS PTHREAD_PROCESS_SHARED 用于同步该进程和其他进程中的线程 USYNC_PROCESS_ROBUST 无 POSIX 等效项 用于在进程间可靠地同步线程 USYNC_THREAD PTHREAD_PROCESS_PRIVATE 用于仅同步该进程中的线程
2023-08-18 23:08:571

windows 互斥量和事件的区别

事件(event)与互斥量(mutex)区别事件(event) 事件是用来同步地位不相等的线程的,事件可以用来使一个线程完成一件事情,然后另外的线程完成剩下的事情。事件的使用很灵活,自动事件的激发态是由人工来控制的,而Mutex在释放(releaseMetux)后就一直处于激发态,直到线程WaitForSingleObject。事件可以用来控制经典的读写模型和生产者和消费者模型。相应的方式为,生成者等待消费者的消费,再消费者消费完后通知生产者进行生产。互斥量(Mutex) Mutex是排他的占有资源,一般用于地位相等的线程进行同步,每个线程都可以排他的访问一个资源或代码段,不存在哪个线程对资源访问存在优先次序。一个线程只能在Mutex处于激发态的时候访问被保护的资源或代码段,线程可以通过WaitForSingelObject来等待Mutex,在访问资源完成之后,ReleaseMutex释放Mutex,此时Mutex处于激发态。Mutex具有成功等待的副作用,在等待到Mutex后,Mutex自动变为未激发态,直到调用ReleaseMutex使Mutex变为激发态为止。自动事件也具有成功等待的副作用。手动事件没有,必须ResetEvent使手动事件变为未激发态。进程和线程也没有成功等待的副作用。当线程或者进程函数返回时,线程内核对象变为激发态,但WaitForSingleObject并没有使线程或者进程的内核对象变为未激发态。总之,事件一般用于控制线程的先后顺序,而Mutex一般用于排他的访问资源。
2023-08-18 23:09:101

c# mutex类和monitor类都是同步操作,有什么区别

hai
2023-08-18 23:09:192

操作系统中wait()用于什么?

甚么操作系统啊?
2023-08-18 23:09:292

mutex=1表示什么意思

没有一个进程进入临界区。互斥信号量,初始值为1,取值范围为(负1,0,1)。当信号量为1时,表示两个进程皆未进入需要互斥的临界区。当信号量为0时,表示有一个进程进入临界区运行,另一个必须等待。当信号量为负1时,表示有一个进程正在临界区运行,另一个进程因等待而阻塞在信号量队列中,需要当前已在临界区运行的进程退出时唤醒。
2023-08-18 23:09:471

操作系统消费者进程中,wait(full)和wait(mutex)顺序不能颠倒?

可能网上有很多说话。下面是我自己的看法。首先,缓冲池为空,就没有没有产品,;full=0,这里还要强调,mutex是全局互斥信号量。这个时候先来了个消费者,他的程序如下:wait(mutex);挂起了,并且占用了mutex,wait(full);……不管来多少消费者,都在mutex队列排队,死锁了。这个时候;生产者,的程序wait(empty);可行wait(mutex):也挂起了, 因为mutex给消费者用了,就是说缓冲区给消费者占用了啦!生产者和消费者都等待了,系统死锁了。希望你能明白我说的。
2023-08-18 23:09:582

请教linux irq 中断能使用mutex互斥锁吗

从 Backtrace 来看,应该是 i2c_transfer 中调用 mutex_lock 导致 schedule 调用而产生 进程调度,导致死机. 而在中断上下文,这种情况是绝对不允许发生的.换句话说是不允许睡眠的,不允许进程调度. 你可以 把 mutex_lock 注释掉再试试 .
2023-08-18 23:10:131

请教linux irq 中断能使用mutex互斥锁吗

从 Backtrace 来看,应该是 i2c_transfer 中调用 mutex_lock 导致 schedule 调用而产生 进程调度,导致死机. 而在中断上下文,这种情况是绝对不允许发生的.换句话说是不允许睡眠的,不允许进程调度. 你可以 把 mutex_lock 注释掉再试试 .
2023-08-18 23:10:201

PTHREAD_MUTEX_INITIALIZER如何理解

有两种方法创建互斥锁,静态方式和动态方式。POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER来静态初始化互斥锁,方法如下: pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; 在LinuxThreads实现中,pthread_mutex_t是一个结构,而PTHREAD_MUTEX_INITIALIZER则是一个结构常量。
2023-08-18 23:10:301

(C语言中)互斥锁的死锁问题

如果你将mutex_c换成mutex_p,则不会死锁,因为,你第一个线程锁上后,切换到第二个线程,因为mutex_p未释放,第二个线程无法获取mutex_p,进入等待状态,此时OS将再次调度第一个线程,直到第一个线程释放mutex_p之后,第二个线程才会被激活,然后调试第二线程,获取mutex_p.使用OS提供的互斥量来保护公共资源还是比较安全的,但如果用二值信号量的话,就可能会有优先级反转的情况.
2023-08-18 23:10:401

多线程安全问题及各种锁

多线程使用不当会出现资源竞争,比如多个线程同时对一块资源进行修改,就会很容易引发数据错乱和数据安全问题。 示例: 以购票系统为例, 对于多线程出现的这种问题,我们的解决办法就是使用线程同步技术,而常见的就是加锁。 2.1 OSSpinLock 自旋锁 自旋锁等待锁的线程会处于忙等(busy-wait)状态,一直占用着CPU资源。 并且现在已经不安全,可能出现优先级反转的问题。 如果等待锁的优先级较高,它会一直占用着CPU的资源,优先级低的线程就无法释放锁。 在iOS10被苹果废弃。由于已经不再安全, 这里不讨论用法了. 2.2 os_unfair_lock 导入头文件 #import <os/lock.h> 调用 ticketTest 方法 打印结果: 2.3 pthread_mutex 互斥锁 普通用法 导入头文件 #import <pthread.h> 调用 ticketTest 方法 打印结果: mutex 也叫“互斥锁”,等待锁的线程处于休眠状态,不是忙等状态。 上面使用的是 Normal 类型同 OSSpinLock 和 os_unfair_lock 作用一样 递归用法 递归锁在被同一线程重复获取时不会产生死锁 递归类型 PTHREAD_MUTEX_RECURSIVE : 条件用法 2.4 NSLock、NSRecursiveLock NSLock 是对 mutex 普通锁的封装 NSRecursiveLock 是对 mutex 递归锁的封装 调用 ticketTest 方法 打印结果: NSRecursiveLock 用法与 NSLock 的用法一样。 2.5 NSCondition NSCondition 是对 mutex 和 cond 的封装 2.6 NSConditionLock 它是对 NSCondition 的进一步封装,可以设置具体的条件值 2.7 dispatch_queue 直接使用GCD的串行队列,也可以实现线程同步 调用ticketTest方法 打印结果: 2.8 dispatch_semaphore 信号量的初始值可以控制线程并发访问的最大值 初始值为1时,代表同时只允许1条线程访问资源,保证线程的同步 调用otherTest会发现每隔两秒打印5条信息。 2.9 @synchronized 是对mutex的递归锁的封装,源码objc4中的objc-sync.mm文件查看 @synchronized(obj)内部会生成obj对应的递归锁,然后进行加锁解锁操作 本文来自: 旺仔大包子 推荐上篇文章: iOS多线程之NSOperation的使用
2023-08-18 23:10:471

《操作系统概念》笔记 临界区问题 - TSL & mutex lock

mutex lock是建立在操作系统给的特殊指令上的一种软件解决方法。 实际上就是test_and_set 以及 compare_and_swap 等指令的高级调用。当然,这里的test and set 和 compare and swap不是具体实现在某个平台的指令,只是抽象的定义了两类的指令。 如果不熟悉test and set的话,那么test and set指令的定义是这样的 当然,这只是定义,整个命令是作为一个atomic的指令的。 利用test and set命令来实现互斥是这个样子的: lock 一开始被初始化为false,然后执行第一句while(tas(&lock)) 的时候 会发生两件事情,第一个就是这句话本身结果是false,这样就允许该线程接着往下执行进入临界区,第二个是这句话将lock赋值成true。 而当lock 取true值的时候,第二个线程如果执行第一句while(tas(&lock))的话,会无限循环busy waiting。就进不了临界区,直到第一个线程将lock 设置为false。 那个时候第一个线程也就已经离开临界区了,就达到了互斥的效果。 compare_and_swap的指令定义如下: 使用cas命令的互斥: cas命令的分析也不难。 以上两个是操作系统提供的硬件的解决方法。但很可惜的是,用户程序一般不用汇编开发。所以类似于pthread ,windows都会提供软件上的解决方法。 最直接的思路就是mutex lock:在进入临界区之前应当获得一个lock,其他没有lock的线程就进入不了临界区,离开临界区应该释放掉这个lock,以便其他线程获得lock。 lock 的两个动作 ---获得,释放的定义如下: 要注意的是,acquire和release都是atomic的。 看到acquire的定义的时候是不是感觉到了一股既视感?回想一下tas里,第一句while执行的时候的两个动作,我们将lock 从 false变成 true,我们 tas指令返回false,从而使得while空循环不执行。 在这里,available默认为true,从而使得while空循环不执行,然后我们将available从true变成了false。 把lock 看成 (!available),我们知道tas固定设置lock = true ,也就是available = false; 这里用tas实现一下acquire : tas(&lock)返回false,进入临界区,同时lock = true 阻碍了其他进程进入临界区。 但是因为tas命令只能实现lock = true 也就是available = false,所以我们无法用它来实现release,这个时候就可以用cas命令 而release实现如下: 当lock = false 的时候,我们将他改变成true。 于是我们现在有了TSL和mutex lock了。
2023-08-18 23:10:551

编译linux-2.6.18内核出错

这个不好查,建议你检查一下配置过程有没有哪儿没有考虑到。
2023-08-18 23:11:021

mutex locked是什么意思

mutex locked互斥锁拼音双语对照双语例句1No two threads can have the same mutex locked at the same time.两个线程不能同时对同一个互斥对象加锁。
2023-08-18 23:11:221

某小型超市,可容纳50人同时购物,入口处有没有

某小型超级市场,可容纳50人同时购物。入口处有篮子,每个购物者可拿一只篮子入内购物。出口处结帐,并归还篮子(出、入口禁止多人同时通过)。试用信号量和P.V操作写出购物者的同步算法。【分析】只有互斥,有两种解法(1)方法一:出入口是同一个进来的人和买完东西的人都走一个口,s = 50;mutex = 1;customer(){while(1){P(S);P(mutex);从入口处进超市,并取一只篮子;V(mutex);进超市内选购商品;P(mutex);到出口结帐,并归还篮子;V(mutex);从出口离开超市;V(S);}}(2)方法二:出入口不是同一个进来的人走入门,买完东西走出口,出口入口都是临界区s = 50;mutex_in = 1;mutex_out = 1;customer(){while(1){P(S);P(mutex_in);从入口处进超市,并取一只篮子;V(mutex_in);进超市内选购商品;P(mutex_out);到出口结帐,并归还篮子;V(mutex_out);从出口离开超市;V(S);}}
2023-08-18 23:11:291

pthread_mutex_lock,为什么下面的程序没有产生死锁呢???

循环等待其实是这样的:检查条件满不满足,不满足就解锁,然后等,等到了要检测的时候,又上锁,然后检查,不满足就解锁。也就是说,进了pthread_cond_wait函数以后,它就释放了lock,然后在has_product上等待,等到has_product被触发了,就再上锁,然后出函数。你的消费者线程调用了pthread_cond_wait以后,就释放了锁,然后这个函数不返回(这个函数不返回你的代码就不会运行下去),等到has_product触发了,这个函数就获取锁,然后返回。再解释一下,就是调用这个函数之前,你这个线程是拿到锁的;出了这个函数,你的线程也还是拿到锁的;但是进了这个函数还没出来的过程中,你的线程会释放锁。
2023-08-18 23:11:371

pthread_mutex_lock的描述

如果互斥锁类型为 PTHREAD_MUTEX_NORMAL,则不提供死锁检测。尝试重新锁定互斥锁会导致死锁。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或未锁定,则将产生不确定的行为。如果互斥锁类型为 PTHREAD_MUTEX_ERRORCHECK,则会提供错误检查。如果某个线程尝试重新锁定的互斥锁已经由该线程锁定,则将返回错误。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。如果互斥锁类型为 PTHREAD_MUTEX_RECURSIVE,则该互斥锁会保留锁定计数这一概念。线程首次成功获取互斥锁时,锁定计数会设置为 1。线程每重新锁定该互斥锁一次,锁定计数就增加 1。线程每解除锁定该互斥锁一次,锁定计数就减小 1。 锁定计数达到 0 时,该互斥锁即可供其他线程获取。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。如果互斥锁类型是 PTHREAD_MUTEX_DEFAULT,则尝试以递归方式锁定该互斥锁将产生不确定的行为。对于不是由调用线程锁定的互斥锁,如果尝试解除对它的锁定,则会产生不确定的行为。如果尝试解除锁定尚未锁定的互斥锁,则会产生不确定的行为。
2023-08-18 23:11:441

请用信号量机制实现这三个进程的同步与互斥活动,并说明所定义的信号量的含义。要求用伪代码描述。

解:缓冲区是一互斥信号量,因此设互斥信号量mutex P1、P2因为奇数的设置与取用而同步,设同步信号量oddP1、P3因为偶数的设置与取用而同步,设同步信号量even;P1、P2、P3因为共享缓冲区,设同步信号量empty。semaphore mutex=1; //缓冲区互斥信号量semaphore odd=0, even=0 //奇数、偶数进程的同步信号量semaphore empty=N //空缓冲区单元个数信号量main( ) cobegin{ process P1 while(true){ number=produce(); p(empty); //递减空缓冲区的单元个数p(mutex); //互斥访问缓冲区put( ); v(mutex); //恢复访问缓冲区if number%2==0 v(even); //为偶数允许取偶数else v(odd); //为奇数允许取奇数} process P2 process P3 while(true){ while(true){ p(odd); //互斥奇数p(even); p(mutex); //互斥访问缓冲区p(mutex); getodd( ); getevend( ); v(mutex); //恢复访问缓冲区v(mutex); v(empty); //递增空缓冲区的单元个数v(empty); countodd(); } counteven();} } coend
2023-08-18 23:12:021

linux 一个线程释放互斥锁后另一个线程为什么不能重新获得互斥锁 代码如下:

函数不全,无法解答
2023-08-18 23:12:103