Delphi 다중 스레드의 스레드 부분 저장 관리
4196 단어 Delphi
여기서는 먼저 스레드 부분 저장에 대해 이야기하고, 다음 편에서는 스레드 동기화에 대해 이야기한다
스레드 로컬 저장소
모든 스레드는 서로 다른 실행 경로를 대표하기 때문에 한 스레드 내부에서만 사용하는 데이터 저장 방식이 가장 좋다.이러한 목적을 달성하려면 다음 세 가지 방법이 있습니다.
1) 첫 번째이자 가장 간단한 방식은 국부 변수(창고에 기반을 둔다)이다.
모든 스레드가 각자의 창고에 있기 때문에 각 스레드는 국부 변수의 사본을 가지고 있기 때문에 서로 영향을 주지 않을 것이다.
2) 두 번째 방법은 관련 정보를 각자의 라인 대상에 저장하는 것이다
3) 세 번째 방식은 Delphi의 키워드threadvar로 변수를 성명하여 운영체제급의 스레드 국부 저장을 이용하는 것이다
1. TThread 파생 대상에 정보 저장
관련 정보를 TThread 파생 대상에 저장하는 것은 루트 부분적으로 선택할 수 있는 기술이다.키워드threadvar를 사용하는 기술에 비해 이런 방식은 더욱 간단하고 효과적이다.예를 들어, 너는 하나의 라인 대상에 아래의 정보를 추가할 수 있다
type
TMyThread = class(TThread)
private
FLocalInt: Integer;
FLocalStr: String;
..
..
end;
알림: 방문 루트 대상의 데이터가 방문 루트의 국부 변수보다 10배 빠르기 때문에, 가능한 한 루트 전용 정보를 루트 대상에 저장해야 합니다.과정이나 함수의 생존 기간에만 의미 있는 변수는 국부 변수로 성명해야 한다
2.threadvar: API 스레드 로컬 스토리지
앞에서 말했듯이 국부 변수는 모든 라인에 하나의 복사본이 있지만 응용 프로그램의 전역 변수는 모든 라인에 의해 공유된다.예를 들어 전역 변수의 값을 설정하고 표시하는 과정이 더 있다고 가정하십시오.문자열을 전달하면 이 전역 변수를 설정합니다.빈 문자열을 전달하면 전체 변수의 값을 표시합니다.이 절차는 다음과 같이 정의됩니다.
var
GolbalStr: String;
procedure SetShowStr(const S: String);
begin
if S = '' then
MessageBox(0, PChar(GlobalStr), 'The string is ...', MB_OK)
else
GlobalStr:= S;
end;
만약 어떤 코드에서 이 과정을 호출한다면 약간의 문제가 발생할 수 있다.그것을 호출할 때, 먼저 설정한 다음에 표시할 수 있기 때문이다.문제는 두 개 이상의 라인이 존재할 수도 있다는 점이다.한 스레드가 이 프로세스를 호출하여 문자열을 설정할 때, 다른 스레드도 이 프로세스를 호출하여 GlobalStr 변수의 값을 설정할 수 있습니다.운영 체제가 CPU 시간을 이전 라인에 다시 분배할 때, 이 라인이 설정한 값은 이미 실망스럽게 잃어버릴 수 있다
이 문제를 해결하기 위해서, Win32는 루트 국부 저장소라고 불리는 방식을 제공합니다. 이것은 첫 번째 실행 루트에서 전역 변수의 복사를 만들 수 있습니다.Delphi는 키워드 threadvar를 이용하여 이 기능을 봉인합니다.
threadvar 키워드에서 국부적으로 저장된 변수를 설명할 수 있습니다.다음은 로컬 변수 GlobalStr에 대한 설명입니다.
threadvar
GlobalStr: String;
다음은 스레드 국부 저장의 용법을 보여 준다.프로그램의 메인 창에 단추가 있습니다. 이 단추를 누르면 Global Str 변수의 값을 설정하고 표시합니다.GlobalStr 변수의 값이 설정되어 표시되는 스레드를 만듭니다.스레드를 만든 후 GlobalStr 변수의 값을 주 스레드에서 다시 설정하고 표시합니다
먼저 var과threadvar로 Global Str 변수를 설명하고 이 프로그램을 실행하면 출력에서 다른 것을 볼 수 있습니다
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMainForm = class(TForm)
Button1:TButton;
procedure Button1Click(Sender: TObject);
private
{...}
public
{...}
end;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
var
//threadvar
GlobalStr: String;
type
TTLSThread = class(TThread)
private
FNewStr: String;
protected
Procedure Execute; override;
public
cpnstructor Create(Const ANewStr: String);
end;
procedure SetShowStr(const S: String);
begin
if S = '' then
MessageBox(0, PChar(GlobalStr), 'The string is ...', MB_OK)
else
GlobalStr:= S;
end;
constructor TTLSThread.Create(const ANewStr: String);
begin
FNewStr:= ANewStr;
inherited Create(False);
end;
procedure TTSThread.Execute;
begin
FreeOnTerminate:= True;
SetShowStr(FNewStr);
SetShowStr('');
end;
procedure TMianForm.Button1Click(Sender: TObject);
begin
SetShowStr('Hello World');
SetShowStr('');
TTLSThread.Create('Dilbert');
Sleep(100);
SetShowStr('');
end;
end.
참고: 데모 프로그램에서 스레드가 생성된 후 Win32 API 프로세스 Sleep()이 호출되었습니다.이 과정의 성명은 다음과 같다.
procedure Sleep(dwMillseconds: DWORD); stdcall;
Sleep () 프로세스는 현재 스레드가 매개 변수dwMillseconds가 지정한 시간 내에 CPU 시간을 분배할 필요가 없다는 것을 운영체제에 알려 줍니다.이 호출을 삽입하는 것은 많은 작업이 발생할 때 어떤 라인을 실행하는지 임의적으로 하는 것입니다
일반적으로, 매개 변수dwMillseconds를 0으로 설정할 수 있습니다. 비록 현재 스레드가 정말로 '수면' 되지는 않지만, 운영체제는 CPU 시간을 다른 우선순위가 같거나 높은 스레드에 나누어 줍니다.
슬립(Sleep)의 신비로운 시간 조정 문제를 조심해야 한다.슬립 () 은 아마도 너의 기계에 특별한 문제가 생겼을 것이다.이런 문제는 다른 기계에서는 재현할 수 없을 것이다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Delphi] TStringBuilder그리고 꼭 사용해야만 할까? 그림처럼 Heap 영역에 "Hello" 공간을 생성하고 포인팅을 한다. "Hello World" 공간을 새로 생성한 후 포인팅을 하게 된다. 결국 "Hello" 라는 String 객체가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.