কাঁটাচামচ () শাখা প্রত্যাশার চেয়ে বেশি?


186

নিম্নলিখিত কোডের অংশটি বিবেচনা করুন:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
    int i;
    for(i = 0; i < 2; i++)
    {
        fork();
        printf(".");
    }
    return 0;
}

এই প্রোগ্রামটি 8 টি বিন্দু আউটপুট করে। এটা কীভাবে সম্ভব? পরিবর্তে 6 টি বিন্দু থাকা উচিত নয়?



উত্তর:


245

fork()আদিম প্রায়ই কল্পনা প্রসারিত। যতক্ষণ না আপনি এটির জন্য কোনও অনুভূতি পান, আপনার প্রতিটি অপারেশন কী তা কাগজে সন্ধান করা উচিত এবং প্রক্রিয়া সংখ্যার জন্য অ্যাকাউন্ট করা উচিত। ভুলে যাবেন না যে কাঁটাচামচ () বর্তমান প্রক্রিয়াটির একটি নিখুঁত-নিখুঁত অনুলিপি তৈরি করে। সর্বাধিক উল্লেখযোগ্য পার্থক্য (বেশিরভাগ উদ্দেশ্যে) হ'ল fork()পিতা-মাতার এবং সন্তানের মধ্যে ফেরতের মান পৃথক। (যেহেতু এই কোডটি ফেরতের মানটিকে উপেক্ষা করে, তাই এটি কোনও পার্থক্য করে না)

সুতরাং, প্রথমদিকে, একটি প্রক্রিয়া আছে। এটি একটি দ্বিতীয় প্রক্রিয়া তৈরি করে, উভয়ই বিন্দু এবং লুপ মুদ্রণ করে। তাদের দ্বিতীয় পুনরাবৃত্তিতে, প্রত্যেকটি অন্য কপি তৈরি করে, সুতরাং চারটি প্রক্রিয়া একটি বিন্দু মুদ্রণ করে, এবং তারপরে প্রস্থান করতে পারে। সুতরাং আমরা সহজেই আপনার প্রত্যাশা মতো ছয়টি বিন্দুর জন্য অ্যাকাউন্ট করতে পারি।

যাইহোক, আসলে printf()কি করে তা তার আউটপুটটি বাফার করে। সুতরাং যখন কেবল দুটি প্রক্রিয়া ছিল তখন থেকে প্রথম বিন্দুটি লেখার সময় উপস্থিত হয় না। এই বিন্দুগুলি বাফারে রয়ে গেছে - যা কাঁটা () এ নকল করা আছে is প্রক্রিয়াটি প্রস্থান হতে চলে না যাওয়ার পরে বাফার ডট প্রদর্শিত হবে। চারটি প্রক্রিয়া একটি বাফার ডট মুদ্রণ করে, এবং নতুনটি 8 টি ডট দেয়।

যদি আপনি এই আচরণটি এড়াতে চান, তবে fflush(stdout);পরে কল করুন printf()


12
ধন্যবাদ, আমি জানতাম না যে বাফারটি কাঁটাচামচ () দিয়ে নকল করে। এটি এমন একটি অদ্ভুত আচরণ ব্যাখ্যা করে।
নিকোলে কোভালেনকো

1
এটি কি 10 টি বিন্দু দেওয়া উচিত নয়, 8? যেহেতু 4 দ্বিতীয় প্রজন্মের বাচ্চারা বাফারড ডট উত্তরাধিকার সূত্রে প্রাপ্ত হয়েছে, তাদের নিজস্ব যুক্ত করবে, তারপরে প্রস্থান করার সময় ফ্লাশ করবে, তারা মোট 8 টি বিন্দু মুদ্রণ করবে তবে তারপরে 2 প্রথম প্রজন্মের প্রক্রিয়াগুলিতে এখনও প্রতিটি বাফার করা একটি বিন্দু থাকবে এবং প্রস্থান করার সময় তাদের ফ্লাশ করবে, মোট 10 দিচ্ছেন
psusi

12
দ্বিতীয় প্রজন্মের প্রক্রিয়ার @psusi এক হয় একটি প্রথম প্রজন্মের প্রক্রিয়া। fork()2 তৈরি করে না তবে প্রস্থান করুন, এটি কেবল আরও 1 টি প্রক্রিয়া তৈরি করে।
ইজকাটা

70

আপনার কাছে আউটপুট স্ট্রীমে মুক্ত বাফার । স্টাডাউটটি লাইন-বাফার হয় এবং বাফারটি বাকি প্রক্রিয়াটির সাথে একত্রে প্রতিলিপি করা হয়। প্রোগ্রামটি শেষ হয়ে গেলে, আপমুক্ত বাফারটি দু'বার লিখিত হয় (প্রতিটি প্রক্রিয়ার জন্য একবার)। উভয় ব্যবহার

printf("a\n");

এবং

printf("a "); fflush(stdout);

সমস্যা প্রদর্শন করবেন না।

আপনার প্রথম উদাহরণে, আপনি চারটি প্রক্রিয়া তৈরি করেন যার প্রতিটি আউটপুট স্ট্রিম বাফারে দুটি বিন্দু রয়েছে। যখন প্রতিটি স্ট্রিমটি শেষ হয়, এটি আটটি বিন্দু উত্পন্ন করে এর বাফারটিকে ফ্লাশ করে।


2

যখন আমি = 0

প্রক্রিয়া_1: বাফার্ড পাঠ্য = 1 ডট

প্রক্রিয়া_2 (প্রক্রিয়া_1 দ্বারা নির্মিত): বাফার্ড পাঠ্য = 1 ডট

যখন আমি = 1

প্রক্রিয়া_3 (প্রক্রিয়া_1 দ্বারা নির্মিত): প্রসেস_1 থেকে 1 টি বাফার ডট উত্তরাধিকারী এবং নিজেই 1 ডট প্রিন্ট করে। মোট প্রক্রিয়া_3 এ 2 টি ডট প্রিন্ট করে।

প্রক্রিয়া ((প্রক্রিয়া ৩ দ্বারা তৈরি করা হয়েছে): প্রক্রিয়া_2 থেকে 1 টি বাফার ডট উত্তরাধিকারী এবং নিজেই 1 ডট প্রিন্ট করে। মোট প্রক্রিয়াতে 2 টি বিন্দু প্রিন্ট করে।

প্রক্রিয়া_1: 2 টি বিন্দু মুদ্রণ করে (i = 0 করার সময় একটি বাফার ডট এবং অন্য = 1 = 1)

প্রক্রিয়া_2: 2 টি বিন্দু মুদ্রণ করে (i = 0 করার সময় একটি বাফার ডট এবং অন্য = 1 = 1)

চূড়ান্ত আউটপুট: 8 টি বিন্দু। :)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.