临界段概念的澄清,对高手来说应当不是一个问题。(50分)

  • 主题发起人 主题发起人 lxggc
  • 开始时间 开始时间
L

lxggc

Unregistered / Unconfirmed
GUEST, unregistred user!
假设有个变量, 有一个线程对其进行 write , 而有一个或多个线程 read 这个变量,这时需要使用临界段吗?why? 最后详细说明
 
我想你得先确定一下临界区的概念,以及你为什么要用临界区!
具体 的楼主自己查吧
对你说的问题,我想应该使用临界区,不然,当你在读的时候,如果你对值进行了修改,那读的就是“脏数据”!
 
你这种情况,如果需要同步的话,还是要做一些工作的,如果允许脏读,那么就可以不用.
如果是一个进程内,就用临界区,如果是两个进程就用信号量.
 
to satanmonkey:
"如果是一个进程内,就用临界区,如果是两个进程就用信号量"
请问在两个进程中如何使用信号量?信号量可以跨进程(不是线程)吗?
 
临界区:使用线程的时候,遇到的一个基本的问题,就是多个线程访问同
一个对象,比如访问相同的文件、DLL、相同的通讯资源,特别是数
据库的访问,当多个线程对同一数据库字段写入的时候,其结果会出
现不确定性。
临界区用于解决这个问题,它可以保证线程使用敏感数据的时候,
阻赛其他的线程访问名干数据,使用时首先要初始化,其声明一个
TRTLCriticalSection类型的变量:
var
CS:TRTLCriticalSection;
初始化:
initializeCriticalSection(cs);
独占
EnterCriticalSection(cs);

解除独占
LeaveCriticalSection(CS);
请注意,临界区只能在一个进程内使用,首先要标记出把数据作为临
界区操作的那些代码,在这部分代码执行前,计算机首先要查看一下全局
记录,已确定是否有其它线程在临界区中,同时也要查看这个临界区是否
和第一个临界区相关,也就是说同一个程序中可能会有几个不同的临界区,
然后计算机再决定运行策略。
 
给你个DEMO;
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
CS:TRTLCriticalSection;
implementation
{$R *.DFM}
uses unit2,unit3;
var thread1:mymath1;
thread2:mymath2;
procedure TForm1.Button1Click(Sender: TObject);
begin
thread1.resume;
thread2.resume;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
initializeCriticalSection(cs);
thread1:=mymath1.create;
thread2:=mymath2.create;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
thread1.suspend;
thread2.suspend;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
thread1.destroy;
thread2.destroy;
thread1:=mymath1.create;
thread2:=mymath2.create;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
thread1.destroy;
thread2.destroy;
Application.Terminate;
end;
end.
//////////////////////////////////////////
unit Unit2;
interface
uses
Windows, Messages, SysUtils,Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,unit1;
type
mymath1 = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
public
constructor create;
end;
implementation
constructor mymath1.create;
begin
inherited create(true);
end;
procedure mymath1.Execute;
var i:integer;
begin
EnterCriticalSection(cs);
for i:=1 to 10000do
form1.edit1.text:=inttostr(i);
LeaveCriticalSection(CS);
end;
end.

/////////////////////////////////////////
unit Unit3;
interface
uses
Windows, Messages, SysUtils,Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,unit1;
type
mymath2 = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
public
constructor create;
end;
implementation
constructor mymath2.create;
begin
inherited create(true);
end;
procedure mymath2.Execute;
var i:integer;
begin
EnterCriticalSection(cs);
for i:=1 to 20000do
form1.edit2.text:=inttostr(i);
LeaveCriticalSection(CS);
end;
end.
 
后退
顶部