এটি কেবল করা যায় না, এটি ব্যাচের ফাইল ছাড়া আর কিছুই করা যায় না! :-)
অস্থায়ী ফাইলটিকে "পাইপ" হিসাবে ব্যবহার করে সমস্যার সমাধান করা যেতে পারে। দ্বি নির্দেশমূলক যোগাযোগের জন্য দুটি "পাইপ" ফাইল দরকার।
প্রক্রিয়া এ "পাইপ 1" থেকে স্টিডিন পড়ে এবং "পাইপ 2" তে স্টডআউট লেখেন
প্রক্রিয়া বি "পাইপ 2" থেকে স্টিডিন পড়ে এবং "পাইপ 1" তে স্টডআউট লেখেন
উভয় ফাইল উভয়ই প্রক্রিয়া চালু করার আগেই বিদ্যমান তা গুরুত্বপূর্ণ। ফাইলগুলি শুরুতে খালি থাকতে হবে।
যদি কোনও ব্যাচ ফাইল কোনও ফাইল থেকে পড়ার চেষ্টা করে যা বর্তমান প্রান্তে ঘটে থাকে, এটি কেবল কিছুই দেয় না এবং ফাইলটি উন্মুক্ত থাকে। সুতরাং আমার রিডলাইন রুটিন অবিরাম খালি অবধি মান না পাওয়া পর্যন্ত অবিচ্ছিন্নভাবে পড়ে।
আমি একটি খালি স্ট্রিং পড়তে এবং লিখতে সক্ষম হতে চাই, তাই আমার রাইটলাইন রুটিনটি একটি অতিরিক্ত চরিত্র যুক্ত করে যা রিডলাইনটি স্ট্রিপ বন্ধ করে দেয়।
আমার A প্রক্রিয়া প্রবাহকে নিয়ন্ত্রণ করে। এটি 1 (বি কে বার্তা) লিখে জিনিসগুলি সূচনা করে এবং 10 টি পুনরাবৃত্তি সহ একটি লুপে প্রবেশ করে যেখানে এটি একটি মান (বি থেকে বার্তা) পড়ে, 1 যোগ করে এবং তারপরে ফলাফলটি লিখে দেয় (বিতে বার্তা)। অবশেষে এটি বি এর শেষ বার্তাটির জন্য অপেক্ষা করে এবং তারপরে বি কে "ছাড়ুন" বার্তা লিখে প্রস্থান করে।
আমার বি প্রক্রিয়াটি একটি শর্তসাপেক্ষে অন্তহীন লুপে রয়েছে যা একটি মান (এ থেকে বার্তা) পড়ে, 10 যোগ করে এবং তারপরে ফলাফলটি লিখে দেয় (এটিকে বার্তা)। বি যদি কখনও "ছাড়ুন" বার্তাটি পড়ে থাকে তবে তা অবিলম্বে বন্ধ হয়ে যায়।
আমি প্রদর্শন করতে চেয়েছিলাম যে যোগাযোগটি পুরোপুরি সুসংগত, সুতরাং আমি এ এবং বি উভয় প্রক্রিয়া লুপের ক্ষেত্রে একটি বিলম্বের পরিচয় দেব।
মনে রাখবেন যে রিডলাইন পদ্ধতিটি একটি শক্ত লুপে রয়েছে যা ইনপুটটির জন্য অপেক্ষা করার সময় ক্রমাগত সিপিইউ এবং ফাইল সিস্টেম উভয়কেই আপত্তিজনকভাবে ব্যবহার করে। লিংকে একটি পিং বিলম্ব যোগ করা যেতে পারে তবে প্রক্রিয়াগুলি তেমন প্রতিক্রিয়াশীল হবে না।
আমি এ এবং বি উভয় প্রসেস চালু করার সুবিধার্থে একটি সত্য পাইপ ব্যবহার করি। তবে পাইপটি অ-কার্যকরী যে কোনও যোগাযোগ এটির মধ্য দিয়ে যায় না। সমস্ত যোগাযোগ আমার অস্থায়ী "পাইপ" ফাইলগুলির মাধ্যমে।
প্রক্রিয়াগুলি আরম্ভ করার জন্য আমি শুরু / বি ব্যবহার করতে পারতাম, তবে তখন আমি তাদের উভয়টি সমাপ্ত হওয়ার সময় সনাক্ত করতে পারি যাতে অস্থায়ী "পাইপ" ফাইলগুলি কখন মুছতে হয় তা আমি জানতে পারি। পাইপটি ব্যবহার করা অনেক সহজ।
আমি সমস্ত কোডকে একটি ফাইলে রেখে দিতে বেছে নিয়েছি - মাস্টার স্ক্রিপ্ট যা A এবং B আরম্ভ করে, পাশাপাশি A এবং B এর কোডও আমি প্রতিটি প্রক্রিয়াটির জন্য একটি পৃথক স্ক্রিপ্ট ফাইল ব্যবহার করতে পারতাম।
test.bat
@echo off
if "%~1" equ "" (
copy nul pipe1.txt >nul
copy nul pipe2.txt >nul
"%~f0" A <pipe1.txt >>pipe2.txt | "%~f0" B <pipe2.txt >>pipe1.txt
del pipe1.txt pipe2.txt
exit /b
)
setlocal enableDelayedExpansion
set "prog=%~1"
goto !prog!
:A
call :writeLine 1
for /l %%N in (1 1 5) do (
call :readLine
set /a ln+=1
call :delay 1
call :writeLine !ln!
)
call :readLine
call :delay 1
call :writeLine quit
exit /b
:B
call :readLine
if !ln! equ quit exit /b
call :delay 1
set /a ln+=10
call :writeLine !ln!
goto :B
:readLine
set "ln="
set /p "ln="
if not defined ln goto :readLine
set "ln=!ln:~0,-1!"
>&2 echo !prog! reads !ln!
exit /b
:writeLine
>&2 echo !prog! writes %*
echo(%*.
exit /b
:delay
setlocal
set /a cnt=%1+1
ping localhost /n %cnt% >nul
exit /b
--OUTPUT--
C:\test>test
A writes 1
B reads 1
B writes 11
A reads 11
A writes 12
B reads 12
B writes 22
A reads 22
A writes 23
B reads 23
B writes 33
A reads 33
A writes 34
B reads 34
B writes 44
A reads 44
A writes 45
B reads 45
B writes 55
A reads 55
A writes 56
B reads 56
B writes 66
A reads 66
A writes quit
B reads quit
উচ্চ স্তরের ভাষার সাথে জীবন কিছুটা সহজ। নীচে A এবং B প্রক্রিয়াগুলির জন্য VBScript ব্যবহার করে এমন একটি উদাহরণ দেওয়া আছে। প্রক্রিয়াগুলি চালু করতে আমি এখনও ব্যাচ ব্যবহার করি। আমি এখানে বর্ণিত একটি খুব শীতল পদ্ধতি ব্যবহার করছি অস্থায়ী ফাইলটি ব্যবহার না করে কোনও ব্যাচ ফাইলের মধ্যে ভিবিএস স্ক্রিপ্ট এম্বেড এবং সম্পাদন করা সম্ভব? একক ব্যাচের স্ক্রিপ্টের মধ্যে একাধিক ভিবিএস স্ক্রিপ্টগুলি এম্বেড করতে।
ভিবিএসের মতো উচ্চতর ভাষার সাথে, আমরা এ থেকে বি তে তথ্য পাস করার জন্য একটি সাধারণ পাইপ ব্যবহার করতে পারি, খ থেকে বি থেকে ক এ তথ্য পাঠানোর জন্য আমাদের কেবলমাত্র একটি অস্থায়ী "পাইপ" ফাইলের প্রয়োজন কারণ আমাদের এখন একটি কার্যকরী পাইপ রয়েছে, এ প্রক্রিয়াটি বিতে "ছাড়ুন" বার্তা প্রেরণের প্রয়োজন হয় না বি-প্রক্রিয়াটি কেবল ফাইল-এর শেষ না হওয়া অবধি লুপ হয়।
এটি নিশ্চিত যে ভিবিএসে একটি সঠিক ঘুমের ক্রিয়ায় অ্যাক্সেস করা ভাল having এটি আমাকে সিপিইউকে বিরতি দেওয়ার জন্য রিডলাইন ফাংশনটিতে খুব সহজেই একটি সংক্ষিপ্ত বিলম্ব প্রবর্তন করতে সক্ষম করে।
যাইহোক, রিডলিনের মধ্যে একটি চুলকানি রয়েছে। প্রথমে আমি মাঝে মাঝে মাঝে ব্যর্থতা পাচ্ছিলাম যতক্ষণ না আমি বুঝতে পারি যে কখনও কখনও রিডলাইন স্টিডিনে তথ্য উপলব্ধ থাকে এবং বিটি লাইনটি লেখার কাজ শেষ করার আগে অবিলম্বে লাইনটি পড়ার চেষ্টা করবে। ফাইল-এর শেষে পরীক্ষা এবং পড়ার মধ্যে একটি সংক্ষিপ্ত বিলম্ব প্রবর্তন করে আমি সমস্যার সমাধান করেছি। 5 এমসেকের বিলম্বটি আমার পক্ষে কৌশলটি করেছে বলে মনে হয়েছিল, তবে আমি নিরাপদ দিকে থাকতে 10 ম্যাসকে দ্বিগুণ করেছি। এটি খুব আকর্ষণীয় যে ব্যাচ এই সমস্যাটি ভোগ করে না। আমরা http://www.dostips.com/forum/viewtopic.php?f=3&t=7078#p47432 এ সংক্ষেপে (৫ টি সংক্ষিপ্ত পোস্ট) আলোচনা করেছি ।
<!-- : Begin batch script
@echo off
copy nul pipe.txt >nul
cscript //nologo "%~f0?.wsf" //job:A <pipe.txt | cscript //nologo "%~f0?.wsf" //job:B >>pipe.txt
del pipe.txt
exit /b
----- Begin wsf script --->
<package>
<job id="A"><script language="VBS">
dim ln, n, i
writeLine 1
for i=1 to 5
ln = readLine
WScript.Sleep 1000
writeLine CInt(ln)+1
next
ln = readLine
function readLine
do
if not WScript.stdin.AtEndOfStream then
WScript.Sleep 10 ' Pause a bit to let B finish writing the line
readLine = WScript.stdin.ReadLine
WScript.stderr.WriteLine "A reads " & readLine
exit function
end if
WScript.Sleep 10 ' This pause is to give the CPU a break
loop
end function
sub writeLine( msg )
WScript.stderr.WriteLine "A writes " & msg
WScript.stdout.WriteLine msg
end sub
</script></job>
<job id="B"> <script language="VBS">
dim ln, n
do while not WScript.stdin.AtEndOfStream
ln = WScript.stdin.ReadLine
WScript.stderr.WriteLine "B reads " & ln
n = CInt(ln)+10
WScript.Sleep 1000
WScript.stderr.WriteLine "B writes " & n
WScript.stdout.WriteLine n
loop
</script></job>
</package>
খাঁটি ব্যাচের সমাধানের সাথে আউটপুট একই, চূড়ান্ত "প্রস্থান" রেখাগুলি না থাকলে।