Шта су нити? и зашто их користимо?
Ранијих дана програмирања сви програми су били једноструки и једноструки задаци у којима ће се ваш програм изводити искључиво на машини или уопште неће радити. Са све софистициранијим апликацијама и све већим захтјевима за персоналним рачунарима, сада су доступни оперативни системи са више процеса и више нити. Multithreading на рачунарском програмирању је углавном био потребан за боље перформансе и употребљивост.
Дакле, прво да пређемо на процес. Процес је програм који ради на систему и користи системске ресурсе као што су CPU, меморија итд. И сваки процес има главну нит. У Процесу се многе радње могу изводити једна по једна у брзом редослиједу.
Thread се генерално користи за обављање неколико скупова радњи одједном у ситуацијама као што неке радње могу изазвати значајно кашњење, али током тог периода програм би требало да буде у стању да изврши и друге радње.
На примјер, у Windows Explorer-у копирамо велику количину података из једне фасцикле у другу фасциклу и открили смо да ће то потрајати, али током копирања можемо да радимо и друге послове. Дакле, у овом случају се процес копирања одвија у новој нити која не утиче на главну нит.
Нити се углавном користе у случају проблема везаних за перформансе. Ево неколико примjера гдjе бисмо могли да користимо нити.
– Дуготрајна обрада: Када Windows апликација израчунава, не може више да обрађује поруке. Као резултат тога, екран се не може ажурирати.
– Обрада у позадини: Неки задаци можда нису временски критични, али морају да се извршавају непрекидно.
– Обављање I/O посла: I/O на диск или у мрежу може имати непредвидива кашњења. Нити вам омогућавају да осигурате да I/O операција не одлаже неповезане делове ваше апликације.
Како ово функционише? Шта ради синхронизација?
Код који се позива када се позове синхронизација може да изврши било шта што би главна VCL нит могла да уради. Поред тога, он такође може да модификује податке повезане са сопственим објектом нити, безбедан у сазнању да је извршење сопствене нити у одређеној тачки (позив за синхронизацију). Оно што се заправо дешава је прилично елегантно и најбоље илуструје још један дијаграм паука.
Када се позове синхронизација, главна нит прорачуна је суспендована. У овом тренутку, главна VCL нит може бити суспендована у стању мировања, може бити привремено суспендована на I/O или другим операцијама, или може да се извршава. Ако није суспендован у потпуно неактивном стању (главна петља порука апликације), онда нит главног прорачуна чека. Када главна нит постане неактивна, функција без параметара прослеђена синхронизацији се извршава у контексту главне VCL нити. У нашем случају, функција без параметара се зове UpdateResults и игра се са белешком. Ово осигурава да неће доћи до сукоба са главном VCL нити, а у суштини, обрада овог кода је слична обради било ког Delphi кода који се јавља као одговор на слање поруке апликацији. Не долази до сукоба са нити која је позвала синхронизацију јер је суспендована на познатој безбједној тачки (негдје у коду за TThread.Sinchronise).
Једном када се ова „обрада путем проксија“ заврши, главна VCL нит је слободна да ради свој нормалан рад, а нит која је позвала синхронизацију се наставља и враћа се из позива функције.
Стога се чини да је позив за синхронизацију још једна порука главној VCL нити и позив функције главној нити прорачуна. Нити су на познатим локацијама и не извршавају се истовремено. Нема услова за трку. Проблем ријешен.
QueryPerformanceCounter (QPC) је функција у Windows API-ју која се користи за мјерење врло прецизних временских интервала.QueryPerformanceFrequency, омогућава корисницима да добију високу прецизност у мјерењу времена, што је корисно за профилисање перформанси апликација. QPC се често користи за временско означавање догађаја и мјерење малих временских интервала унутар истог система или виртуелне машине.QueryPerformanceFrequency омогућава корисницима да добију високу прецизност у мјерењу времена, што је корисно за профилисање перформанси апликација. QPC се често користи за временско означавање догађаја и мјерење малих временских интервала унутар истог система или виртуелне машине.
uses
Windows, SysUtils;
var
Frequency, StartCounter, EndCounter: Int64;
ElapsedTime: Double;
begin
// Dobijanje frekvencije visoko preciznog tajmera
if QueryPerformanceFrequency(Frequency) then
begin
// Mjerenje vremena
QueryPerformanceCounter(StartCounter);
// Ovdje dodajte kod koji želite mjeriti, na primer:
Sleep(1000); // Simulira proces koji traje 1 sekundu
QueryPerformanceCounter(EndCounter);
// Izračunavanje proteklog vremena u sekundama
ElapsedTime := (EndCounter - StartCounter) / Frequency;
// Prikaz rezultata
Writeln(Format('Proteklu vreme: %.6f sekundi', [ElapsedTime]));
end
else
begin
Writeln(‘Sistem ne podržava funkciju
QueryPerformanceFrequency.’);
end;
Readln; // Čekanje na unos
end.
Windows se koristi za pristup funkcijama Windows API-ja.QueryPerformanceFrequency(Frequency) postavlja varijablu Frequency sa frekvencijom tajmera u Hertzima. Ako funkcija vrati True, sistem podržava ovu funkcionalnost.QueryPerformanceCounter se koristi da zabeleži vreme pre i posle izvršavanja nekog bloka koda. Rezultati su u jedinicama koje zavise od frekvencije.EndCounter i StartCounter podeljena sa Frequency daje vreme u sekundama.Writeln da prikažemo proteklo vreme.Овај код ће приказати колико је времена протекло у секунди за одређене операције које сте одабрали. Можете га прилагодити према вашим потребама за мјерење перформанси.
QueryPerformanceCounter – преузима тренутну вриједност бројача перформанси, што је временска ознака високе резолуције (<1us) која се може користити за мерења временског интервала. QueryPerformanceFrequency – Преузима фреквенцију бројача перформанси. Учесталост бројача перформанси је фиксна при покретању система и конзистентна је на свим процесорима. Зато је потребно да захтјевате фреквенцију само након иницијализације апликације, а резултат се може кеширати. Да бисмо користили ове функције за бројање временског интервала потребног за извршење било које операције у Delphi-ју, потребно је да уредимо изворни код, на примјер, на следећи начин:
var iCounterPerSec: TLargeInteger; T1, T2: TLargeInteger; //counter value BEFORE and AFTER the operation begin QueryPerformanceFrequency(iCounterPerSec);//determine the frequency of the counter QueryPerformanceCounter(T1); //mark the start of the operation DoSomething; //execute the operation QueryPerformanceCounter(T2);//mark the end of the operation ShowMessage(FormatFloat(‘0.0000’, (T2 – T1)/iCounterPerSec) + ‘ сек.’);//show the required number of seconds to complete the operation end;
Можете да радите са добијеним вриједностима Т1 и Т2 како желите, на примјер, можете засебно приказати минуте / секунде / милисекунде итд. Ово зависи од ваших потреба и жеља. У овом чланку сам показао најједноставнији примјер коришћења бројача високе резолуције у Delphi-ју. Модул System.Diagnosticsје уведен у Delphi прилично давно. Модул обезбjеђује само један запис – TStopwatch. То је у суштини згодан „омот“ за коришћење тајмера високе резолуције у вашим апликацијама на више платформи. TStopwatchкористи функционалност која зависи од оперативног система за приступ тајмерима високе резолуције ако су доступни. Ако тајмери високе резолуције нису доступни у ОС, користе се уобичајени тајмери. Иако TStopwatchје запис, и даље морате да позовете методу Create или StartNev да бисте је правилно користили. Опис TStopwatchје следећи:
TStopwatch = record
strict private
class var FFrequency: Int64;
class var FIsHighResolution: Boolean;
class var TickFrequency: Double;
strict private FElapsed: Int64;
FRunning: Boolean;
FStartTimeStamp: Int64;
function GetElapsed: TTimeSpan;
function GetElapsedDateTimeTicks: Int64;
function GetElapsedMilliseconds: Int64;
function GetElapsedTicks: Int64;
class procedure InitStopwatchType; static;
public class function Create:
TStopwatch; static;
class function GetTimeStamp: Int64; static;
procedure Reset;
procedure Start;
class function StartNew: TStopwatch; static;
procedure Stop;
property Elapsed: TTimeSpan read GetElapsed;
property ElapsedMilliseconds: Int64 read GetElapsedMilliseconds;
property ElapsedTicks: Int64 read GetElapsedTicks;
class property Frequency: Int64 read FFrequency;
class property IsHighResolution: Boolean read FIsHighResolution;
property IsRunning: Boolean read FRunning;
end;
IsHighResolution одређује да ли је тајмер заснован на бројачу перформанси високе резолуције.Start() почиње да мери протекло време.Stop() престаје да мери протекло време.ElapsedMilliseconds добија укупно протекло време у милисекундама.Elapsed добија протекло време у облику TTimeSpan.uses System.Diagnostics; … var SW: TStopwatch; begin SW:=TStopwatch.StartNew; SW.Start; DoSomething; SW.Stop; ShowMessage(SW.Elapsed.TotalMinutes.ToString); end;
Delphi-ју, прије свега, морате да одлучите која прецизност вам одговара:
Now () функцију. Да, тачност је најнижа, али, с друге стране, овај метод је апсолутно једноставан.GetTickCount() која је једноставна и поуздана, али само ако не планирате да мјерите временски интервал који ће бити дужи од 49,7 дана.QueryPerformanceCounter()и QueryPerformanceFrequency() .TStopwatchу System.Diagnosticsмодулу. Ово је најпогодније за апликације на више платформи јер ради на било чему укључујући Windows, Linux, Android и macOS.Преузето са :
Најбољи Вордпресов плагин за доставу :
WC Hide Shipping Methods
Сакрива другу опцију, а оставља само ону коју треба.
Ако клијент има и физичке локације, тад овако нешто највише одговара.
До неке цијене иду опције A) фиксна цијена, B) лично преузимање.
Преко дефинисаног износа се приказују опције A) бесплатна достава, B) лично преузимање
// Uklanjanje fixed rate dostave kada je besplatna dostupna
function hide_shipping_when_free_is_available( $rates, $package ) {
$new_rates = array();
foreach ( $rates as $rate_id => $rate ) {
// Izmena samo ako je besplatna dostupna
if ( 'free_shipping' === $rate->method_id ) {
$new_rates[ $rate_id ] = $rate;
break;
}
}
if ( ! empty( $new_rates ) ) {
// Prikazi i licno preuzimanje ako je omoguceno
foreach ( $rates as $rate_id => $rate ) {
if ('local_pickup' === $rate->method_id ) {
$new_rates[ $rate_id ] = $rate;
break;
}
}
return $new_rates;
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );
Да бисте направили макро за аутоматско освјежавање свих пивот табела у Excel-у, пратите следеће кораке:
Отворите Excel.
Притисните Alt + F11 да отворите VBA едитор.
У VBA едитору, десни клик на било који од објеката у "Project Explorer" прозору (обично са лијеве стране).
ИзаберитеInsert>Module. Ово ће прокламовати нови модул.
У прозору модула који се отвори, унесите следећи код:
Sub RefreshAllPivotTables() Dim ws As Worksheet Dim pt As PivotTable ' Prolazak kroz sve radne listove For Each ws In ThisWorkbook.Worksheets ' Prolazak kroz sve Pivot tabele na svakom radnom listu For Each pt In ws.PivotTables pt.RefreshTable Next pt Next ws MsgBox "Sve Pivot tabele su osvežene!", vbInformation
Притисните Ctrl + S да сачувате свој рад и затворите VBA едитор.
Вратите се у Excel.
Притисните Alt + F8 да отворите прозор за покретање макроа.
ИзаберитеRefreshAllPivotTablesи кликните наRun.
Ако желите да омогућите једноставно покретање, можете додати дугме на радни лист и доделити му макро:
Пређите на Developer tab (ако га немате, можете га додати путем опција).
Изаберите Insert и изаберте тип дугмета из Form Controls.
Нацртајте дугме на радном листу, и од вас ће бити затражено да додјелите макро.
Изаберите RefreshAllPivotTable и кликните ОК.
Сада ћете моћи да освјежите све пивот табеле једним кликом на дугме !