প্রি-প্রিমিটিভ ওএসের সুবিধা কী? এবং এই সুবিধার জন্য দাম?


14

বেয়ারড মেটাল এমসিইউর জন্য, ব্যাকগ্রাউন্ড লুপ প্লাস টাইমার বিঘ্নিত আর্কিটেকচারের সাথে হোমমেড কোডের সাথে তুলনা করা, প্রি-প্রিমিটিভ ওএসের সুবিধা কী? এই প্রকল্পগুলির মধ্যে কোনটি কোনও প্রজেক্টের জন্য প্রি-প্রিমিটিভ ওএস গ্রহণের জন্য ব্যাকগ্রাউন্ড লুপ আর্কিটেকচার সহ হোমমেড কোড ব্যবহার করার চেয়ে যথেষ্ট আকর্ষণীয়?

প্রশ্নের ব্যাখ্যা:

যারা আমার প্রশ্নের উত্তর দিয়েছেন তাদের আমি সত্যিই প্রশংসা করি। আমার মনে হয় উত্তরটি প্রায় হয়েছে। আমি এখানে আমার প্রশ্নের সাথে এই ব্যাখ্যাটি যুক্ত করছি যা আমার নিজস্ব বিবেচনা দেখায় এবং প্রশ্নটি সংকীর্ণ করতে বা আরও সুনির্দিষ্ট করতে সহায়তা করতে পারে।

আমি যা করার চেষ্টা করছি তা হল সাধারণভাবে কোনও প্রকল্পের জন্য কীভাবে সবচেয়ে উপযুক্ত আরটিওএস চয়ন করতে হয় তা বোঝা।
এটি অর্জনের জন্য, বিভিন্ন ধরণের আরটিওএস এবং এর সাথে সম্পর্কিত দামের মূল ধারণাগুলি এবং সর্বাধিক আকর্ষণীয় সুবিধাগুলি সম্পর্কে আরও ভাল বোঝা সহায়তা করবে, কারণ সমস্ত অ্যাপ্লিকেশনের জন্য সেরা আরটিওএস নেই।
আমি কয়েক বছর আগে ওএস সম্পর্কে বইগুলি পড়েছিলাম তবে আমার কাছে সেগুলি আর নেই। আমি আমার প্রশ্ন এখানে পোস্ট করার আগে আমি ইন্টারনেটে অনুসন্ধান করেছি এবং এই তথ্যটি সবচেয়ে সহায়ক বলে মনে হয়েছিল: http://www.ustudy.in/node/5456
আরও অনেক সহায়ক তথ্য রয়েছে যেমন বিভিন্ন আরটিওএসের ওয়েবসাইটের সূচনা, প্রি-এমপ্যটিভ শিডিয়ুলিং এবং অ-প্রাক-পূর্বসূচি নির্ধারণের তুলনা প্রবন্ধ এবং ইত্যাদি etc.
তবে কখনই প্রি-প্রিম্পটিভ আরটিওএস চয়ন করবেন এবং টাইমারের বিঘ্ন এবং ব্যাকগ্রাউন্ড লুপটি ব্যবহার করে আপনার নিজের কোডটি লিখুন কখন তা উল্লেখ করা কোনও বিষয় খুঁজে পেলাম না।
আমার নিজের নিজস্ব উত্তর রয়েছে তবে আমি সেগুলি নিয়ে যথেষ্ট সন্তুষ্ট নই।
আমি উত্তরটি জানতে চাই বা আরও বেশি অতিশয় লোকের কাছ থেকে বিশেষত শিল্প চর্চায় দেখতে চাই।

এ পর্যন্ত আমার বোঝাপড়াটি হ'ল:
কোনও ওএস ব্যবহার বা ব্যবহার না করা, নির্দিষ্ট ধরণের শিডিয়ুলিং কোডগুলি সর্বদা প্রয়োজনীয়, এমনকি এটি কোডের আকারেও থাকে:

    in the timer interrupt which occurs every 10ms  
    if(it's 10ms)  
    {  
      call function A / execute task A;  
    }  
    if(it's 50ms)  
    {  
      call function B / execute task B;  
    }  

সুবিধা 1:
একটি অ-প্রিম্পিমটিভ ওএস শিডিয়ুলিং কোডের জন্য উপায় / প্রোগ্রামিং স্টাইলকে নির্ধারণ করে, যাতে প্রকৌশলীরা আগে একই প্রকল্পে না থাকলেও একই মতামতটি ভাগ করতে পারে। তারপরে কনসেপ্ট টাস্ক সম্পর্কে একই দৃষ্টিভঙ্গি সহ ইঞ্জিনিয়াররা বিভিন্ন কার্যক্রমে কাজ করতে পারেন এবং তাদের পরীক্ষা করতে পারেন, যথাসম্ভব স্বতন্ত্রভাবে তাদের প্রোফাইল দিতে পারেন।
তবে আমরা এর থেকে কতটা অর্জন করতে পারি? ইঞ্জিনিয়াররা যদি একই প্রকল্পে কাজ করে থাকে তবে তারা অ-প্রিম্পিটিভ ওএস ব্যবহার না করে একই দর্শনটি ভালভাবে ভাগ করে নিতে পারে।
একজন ইঞ্জিনিয়ার যদি অন্য প্রকল্প বা সংস্থার হয় তবে ওএসের আগে জানলে সে সুবিধাটি অর্জন করবে। তবে যদি সে তা না করে, তবে আবারও মনে হচ্ছে যে কোনও নতুন ওএস বা কোডের একটি নতুন অংশ শিখতে তার পক্ষে বড় পার্থক্য তৈরি হবে না।

সুবিধা 2:
যদি ওএস কোডটি ভালভাবে পরীক্ষা করা হয় তবে এটি ডিবাগিং থেকে সময় বাঁচায়। এটি সত্যিই একটি ভাল সুবিধা।
তবে যদি অ্যাপ্লিকেশনটিতে কেবল প্রায় 5 টি কার্য থাকে তবে আমি মনে করি টাইমার বিঘ্ন এবং ব্যাকগ্রাউন্ড লুপ ব্যবহার করে আপনার নিজের কোডটি লেখা সত্যিই অগোছালো নয়।

এখানের একটি প্রাক-প্রিম্পিটিভ ওএসকে একটি প্রি-প্রিমিটিভ শিডিয়ুলার সহ বাণিজ্যিক / ফ্রি / লেগ্যাসি ওএসকে উল্লেখ করা হয়।
আমি যখন এই প্রশ্নটি পোস্ট করেছি, আমি সাধারণত কয়েকটি ওএসের মতো চিন্তা করি:
(1) কেআইএসএস কার্নেল (একটি ছোট ননপ্রিমিটিভ আরটিওএস - এর ওয়েবসাইট দাবি করেছে)
http://www.frontiernet.net/~rhode/kisskern.html
(2) uSmartX (লাইটওয়েট আরটিওএস - এর ওয়েবসাইট দ্বারা দাবি করা)
(3) ফ্রিআরটিওস (এটি একটি প্রাকদর্শী আরটিওএস, তবে আমি যেমন বুঝতে পেরেছি, এটি একটি প্রি-প্রিমিটিভ আরটিওএস হিসাবেও কনফিগার করা যেতে পারে)
(4) ইউসি / ওএস (ফ্রিআরটিওএসের মতো)
(5 ) কিছু সংস্থায় লিগ্যাসি ওএস / শিডিয়ুলার কোড (সাধারণত অভ্যন্তরীণভাবে সংস্থা দ্বারা তৈরি এবং রক্ষণাবেক্ষণ করা হয়)
(নতুন স্ট্যাকওভারফ্লো অ্যাকাউন্ট থেকে সীমাবদ্ধতার কারণে আরও লিঙ্ক যুক্ত করা যায় না)

যেমনটি আমি বুঝতে পেরেছি, একটি অ-প্রাক-প্রিমিটিভ ওএস হ'ল এই কোডগুলির সংকলন:
(1) অ-প্রাক-কৌশলগত কৌশল ব্যবহার করে একটি শিডিয়ুলার।
(২) আন্তঃ টাস্ক যোগাযোগ, মুটেক্স, সিঙ্ক্রোনাইজেশন এবং সময় নিয়ন্ত্রণের জন্য সুবিধা।
(3) মেমরি পরিচালনা।
(4) অন্যান্য কার্যকরী সুবিধা / ফাইল সিস্টেম, নেটওয়ার্ক স্ট্যাক, গুই এবং ইত্যাদি লাইব্রেরি (FreeRTOS এবং UC / অপারেটিং সিস্টেম এই প্রদান করে, কিন্তু আমি নিশ্চিত যদি তারা এখনও কাজ যখন নির্ধারণকারী অ স্বতপ্রণোদিত যেমন কনফিগার করা নই)
কিছু তাদের সবসময় হয় না। তবে শিডিয়ুলার আবশ্যক।


সংক্ষেপে এটি বেশ। আপনার যদি এমন কোনও কাজের চাপ থাকে যা মাল্টিথ্রেড করা দরকার এবং আপনি ওভারহেড সামর্থ্য করতে পারেন, একটি থ্রেডিং ওএস ব্যবহার করুন। অন্যথায় একটি সাধারণ সময় বা টাস্ক-ভিত্তিক "শিডিয়ুলার" বেশিরভাগ ক্ষেত্রেই যথেষ্ট। এবং প্রিপ্রিটিভ বা কো-অপারেটিভ মাল্টিটাস্কিং সেরা কিনা তা নির্ধারণ করার জন্য ... আমি অনুমান করি যে এটি ওভারহেডে নেমে এসেছে এবং আপনার যে মাল্টিটাস্কিংয়ের দরকার তা আপনার কতটা নিয়ন্ত্রণ রাখতে চান।
akohlsmith

উত্তর:


13

এটি কিছুটা টপ-টপিকের গন্ধ পাচ্ছে তবে আমি এটিকে ট্র্যাক থেকে ফিরিয়ে আনার চেষ্টা করব।

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

একটি নির্বিচারে উদাহরণ: ধরা যাক আপনি মাল্টিথ্রেডেড এমবেডেড সিস্টেমে নতুন এবং আপনার একটি আই 2 সি এডিসি, একটি এসপিআই এলসিডি এবং একটি আই 2 সি ইপ্রোম রয়েছে। আপনি সিদ্ধান্ত নিয়েছেন যে দুটি থ্রেড থাকা ভাল ধারণা হবে: একটি যা এডিসি থেকে পড়ে EEPROM কে নমুনাগুলি লিখে দেয় এবং একটি যা সর্বশেষ 10 টি নমুনা পড়ে, সেগুলি গড় হয় এবং এসপিআই এলসিডিতে প্রদর্শন করে। অনভিজ্ঞ ডিজাইনটি দেখতে এরকম কিছু হবে (সম্পূর্ণ সরলীকৃত):

char i2c_read(int i2c_address, char databyte)
{
    turn_on_i2c_peripheral();
    wait_for_clock_to_stabilize();

    i2c_generate_start();
    i2c_set_data(i2c_address | I2C_READ);
    i2c_go();
    wait_for_ack();
    i2c_set_data(databyte);
    i2c_go();
    wait_for_ack();
    i2c_generate_start();
    i2c_get_byte();
    i2c_generate_nak();
    i2c_stop();
    turn_off_i2c_peripheral();
}

char i2c_write(int i2c_address, char databyte)
{
    turn_on_i2c_peripheral();
    wait_for_clock_to_stabilize();

    i2c_generate_start();
    i2c_set_data(i2c_address | I2C_WRITE);
    i2c_go();
    wait_for_ack();
    i2c_set_data(databyte);
    i2c_go();
    wait_for_ack();
    i2c_generate_start();
    i2c_get_byte();
    i2c_generate_nak();
    i2c_stop();
    turn_off_i2c_peripheral();
}

adc_thread()
{
    int value, sample_number;

    sample_number = 0;

    while (1) {
        value = i2c_read(ADC_ADDR);
        i2c_write(EE_ADDR, EE_ADDR_REG, sample_number);
        i2c_write(EE_ADDR, EE_DATA_REG, value);

        if (sample_number < 10) {
            ++sample_number;
        } else {
            sample_number = 0;
        }
    };
}

lcd_thread()
{
    int i, avg, sample, hundreds, tens, ones;

    while (1) {
        avg = 0;
        for (i=0; i<10; i++) {
            i2c_write(EE_ADDR, EE_ADDR_REG, i);
            sample = i2c_read(EE_ADDR, EE_DATA_REG);
            avg += sample;
        }

        /* calculate average */
        avg /= 10;

        /* convert to numeric digits for display */
        hundreds = avg / 100;
        tens = (avg % 100) / 10;
        ones = (avg % 10);

        spi_write(CS_LCD, LCD_CLEAR);
        spi_write(CS_LCD, '0' + hundreds);
        spi_write(CS_LCD, '0' + tens);
        spi_write(CS_LCD, '0' + ones);
    }
}

এটি একটি খুব অশোধিত এবং দ্রুত উদাহরণ। এই মত কোড না!

এখন মনে রাখবেন, প্রি-ইম্পিটিভ মাল্টিটাস্কিং ওএস কোডের যে কোনও লাইনে এই থ্রেডগুলির মধ্যে কোনওটি স্থগিত করতে পারে (আসলে কোনও সমাবেশের নির্দেশে) এবং অন্য থ্রেডটি চালানোর জন্য সময় দিতে পারে।

সেইটার জন্য ভাবেন. ওএস যদি adc_thread()সত্যিকারের ডেটা লিখতে এবং লেখার জন্য EE ঠিকানার সেটিংসের মধ্যে স্থগিত করার সিদ্ধান্ত নেয় তবে কী হবে তা কল্পনা করুন । lcd_thread()দৌড়াতে হবে, প্রয়োজনীয় ডেটা পড়তে আই 2 সি পেরিফেরিয়ালের সাথে গোছানো হবে এবং যখন adc_thread()আবার চালানোর পালা পেল তখন ইপ্রোম একই অবস্থায় থাকবে না এটি ছেড়ে দেওয়া হয়েছিল। জিনিসগুলি মোটেই খুব ভাল কাজ করবে না। সবচেয়ে খারাপটি, এটি এমনকি বেশিরভাগ সময় কার্যকর হতে পারে তবে পুরো সময়টি নয় এবং আপনি যদি নিজের কোডটি পছন্দ করেন না কেন এটি কোড কেন কাজ করছে না তা জানার চেষ্টা করে পাগল হয়ে যাবেন!

এটি সেরা ক্ষেত্রে উদাহরণ; ওএস সিদ্ধান্ত নিতে পারে প্রেক্ষাপট i2c_write()থেকে প্রাক-ফাঁকা করার adc_thread()এবং এটি আবার lcd_thread()এর প্রসঙ্গে থেকে চালানো শুরু করবে ! জিনিসগুলি সত্যিই দ্রুত অগোছালো হয়ে উঠতে পারে।

যখন আপনি একটি প্রাক-উদ্বোধনী মাল্টিটাস্কিং পরিবেশে কাজ করার জন্য কোড লিখছেন তখন আপনাকে লকিং পদ্ধতি ব্যবহার করতে হবে তা নিশ্চিত করার জন্য যে আপনার কোডটি যদি অপ্রয়োজনীয় সময়ে স্থগিত করা হয় যে সমস্ত নরকে looseিলে না যায়।

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

char getch()
{
    while (! (*uart_status & DATA_AVAILABLE)) {
        /* do nothing */
    }

    return *uart_data_reg;
}

void putch(char data)
{
    while (! (*uart_status & SHIFT_REG_EMPTY)) {
        /* do nothing */
    }

    *uart_data_reg = data;
}

void echo_thread()
{
    char data;

    while (1) {
        data = getch();
        putch(data);
        yield_cpu();
    }
}

void seconds_counter()
{
    int count = 0;

    while (1) {
        ++count;
        sleep_ms(1000);
        yield_cpu();
    }
}

আপনার কোডটি কীভাবে মনে হয় সেই কোডটি কাজ করবে না বা এটি কাজ করে বলে মনে হলেও, ইকো থ্রেডের ডেটার হার বাড়ার সাথে সাথে এটি কাজ করবে না। আবার, এটি দেখতে এক মিনিট সময় নেওয়া যাক।

echo_thread()কোনও ইউআরটিতে উপস্থিত বাইটের জন্য অপেক্ষা করে এবং পরে এটি পেয়ে এবং এটি লেখার জায়গা না পাওয়া পর্যন্ত অপেক্ষা করে, তারপরে এটি লিখুন। এটি সম্পন্ন হওয়ার পরে এটি অন্যান্য থ্রেডগুলিকে চালানোর পালা দেয়। seconds_counter()একটি গণনা বৃদ্ধি করবে, 1000 মিমি অপেক্ষা করবে এবং তারপরে অন্যান্য থ্রেডগুলিকে চালানোর সুযোগ দেবে। যদি দীর্ঘক্ষণ ঘটে যাওয়ার সময় দুটি বাইট যদি ইউআরটিতে আসে তবে আপনি সেগুলি দেখতে ভুলে sleep()যেতে পারেন কারণ সিপিইউ অন্যান্য কাজে ব্যস্ত থাকাকালীন আমাদের অনুমানী UART- তে অক্ষর সংরক্ষণ করার কোনও ফিফো নেই।

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

এখন এটি একটি টাইমার এবং পটভূমি লুপ সঙ্গে কি করতে হবে? টাইমার এবং পটভূমি লুপ উপরের সমবায় মাল্টিটাস্কিং উদাহরণের সাথে খুব মিল:

void timer_isr(void)
{
    ++ticks;
    if ((ticks % 10)) == 0) {
        ten_ms_flag = TRUE;
    }

    if ((ticks % 100) == 0) {
        onehundred_ms_flag = TRUE;
    }

    if ((ticks % 1000) == 0) {
        one_second_flag = TRUE;
    }
}

void main(void)
{
    /* initialization of timer ISR, etc. */

    while (1) {
        if (ten_ms_flag) {
            if (kbhit()) {
                putch(getch());
            }
            ten_ms_flag = FALSE;
        }

        if (onehundred_ms_flag) {
                    get_adc_data();
            onehundred_ms_flag = FALSE;
        }

        if (one_second_flag) {
            ++count;
                    update_lcd();
            one_second_flag = FALSE;
        }
    };
}

এটি সমবায় থ্রেডিং উদাহরণের খুব কাছাকাছি দেখায়; আপনার একটি টাইমার রয়েছে যা ইভেন্টগুলি সেট করে এবং একটি প্রধান লুপ যা সেগুলির জন্য সন্ধান করে এবং সেগুলিতে একটি পারমাণবিক ফ্যাশনে কাজ করে। একে অপরের সাথে হস্তক্ষেপকারী এডিসি এবং এলসিডি "থ্রেডস" সম্পর্কে আপনাকে চিন্তা করার দরকার নেই কারণ একজন কখনও অন্যকে বাধা দেয় না। আপনার এখনও "থ্রেড" খুব বেশি সময় নিবে তা নিয়ে চিন্তা করতে হবে; উদাহরণস্বরূপ, যদি 30 get_adc_data()এসএম লাগে তবে কী হয় ? আপনি একটি চরিত্র পরীক্ষা করার জন্য এবং এটি প্রতিধ্বনি করার জন্য তিনটি সুযোগ হাতছাড়া করবেন।

লুপ + টাইমার বাস্তবায়ন প্রায়শই সমবায় ভিত্তিক মাল্টিটাস্কযুক্ত মাইক্রোকার্নেলের চেয়ে প্রয়োগ করা অনেক সহজ কারণ আপনার কোডটি হাতের কাজটির জন্য আরও নির্দিষ্টভাবে নকশাকৃত করা যেতে পারে। আপনি একটি নির্দিষ্ট সিস্টেম ডিজাইনিং করার মতো সত্যিকার অর্থে এতগুলি মাল্টিটাস্কিং করছেন না যেখানে আপনি প্রতিটি উপ-সিস্টেমকে খুব নির্দিষ্ট এবং অনুমানযোগ্য উপায়ে তার কাজগুলি করার জন্য কিছুটা সময় দিন। এমনকি একটি সমবায় মাল্টিটাস্ক সিস্টেমে প্রতিটি থ্রেডের জন্য একটি জেনেরিক টাস্ক কাঠামো থাকতে হয় এবং পরবর্তী থ্রেডটি চালানোর জন্য একটি নির্ধারিত ফাংশন দ্বারা নির্ধারিত হয় যা বেশ জটিল হয়ে উঠতে পারে।

তিনটি সিস্টেমের জন্য লক করার পদ্ধতিগুলি একই, তবে প্রতিটিটির জন্য প্রয়োজনীয় ওভারহেডটি একেবারেই আলাদা।

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

এখানে একটি কথাও আছে যে থ্রেডে কাজ করা যে কেউ প্রশংসা করবে:

if you have a problem and use threads to solve it, yoeu ndup man with y pemro.bls

:-)


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

আপনি কি এই আরও কিছু কাজ করতে পারেন?
ইলিশ

ধন্যবাদ, akohlsmith। আপনি যে বাক্যটি শেষে দিয়েছেন তা আমার পছন্দ হয়েছে। এটি সনাক্ত করতে আমার কিছুটা সময় লেগেছিল :) আপনার উত্তরের পয়েন্টে ফিরে আপনি প্রায় সর্বদা লুপ + টাইমার বাস্তবায়নে কোড করেন। তারপরে, যে ক্ষেত্রে আপনি এই বাস্তবায়নটি ছেড়ে দিয়েছেন এবং অ-প্রাক-প্রাকৃতিক ওএসের দিকে ফিরেছেন, কী কারণে আপনি তা করতে পেরেছেন?
হাইল্যাং

যখন আমি অন্য কারও ওএস চালাচ্ছিলাম তখন আমি সমবায় এবং প্রিমিটিভ মাল্টিটাস্কিং সিস্টেম উভয়ের সাথেই চলেছি। হয় লিনাক্স, থ্রেডএক্স, ucOS-ii বা কিউএনএক্স। এমনকি সেই পরিস্থিতিতে কয়েকটিতে, আমি সাধারণ এবং কার্যকর টাইমার + ইভেন্ট লুপ ব্যবহার করেছি ( poll()সাথে সাথে মনে আসে))
akohlsmith

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

6

অনেকগুলি মাইক্রোকন্ট্রোলার প্রকল্পগুলিতে মাল্টি-টাসিং একটি দরকারী বিমূর্ততা হতে পারে, যদিও সত্যিকারের প্রাক-কর্মক্ষম সময়সূচী বেশিরভাগ ক্ষেত্রেই ভারী ওজনযুক্ত এবং অপ্রয়োজনীয় হবে be আমি 100 টিরও বেশি মাইক্রোকন্ট্রোলার প্রকল্প ভাল করেছি। আমি বেশ কয়েকবার সমবায় কাজে ব্যবহার করেছি, তবে এর সাথে সম্পর্কিত ব্যাগেজের সাথে প্রাক-আগ্রাসী কাজটি এখন পর্যন্ত যথাযথ হয়নি।

কো-অপারেটিভ টাস্কিংয়ের ক্ষেত্রে প্রি-ইম্পেটিভ টাস্কিংয়ের সমস্যাগুলি হ'ল:

  1. অনেক বেশি ভারী ওজন প্রাক-উদ্দীপক টাস্ক শিডিয়ুলারগুলি আরও জটিল, আরও কোড স্পেস নিন এবং আরও চক্র গ্রহণ করুন। তাদের কমপক্ষে একটি বাধাও প্রয়োজন। এটি প্রায়শই প্রয়োগের ক্ষেত্রে একটি অগ্রহণযোগ্য বোঝা।

  2. একযোগে অ্যাক্সেস করা যেতে পারে এমন কাঠামোগুলির চারপাশে নিঃশব্দগুলির প্রয়োজন। একটি সমবায় সিস্টেমে পারমাণবিক ক্রিয়াকলাপ কী হওয়া উচিত তার মাঝামাঝি আপনি কেবল TASK_YIELD কল করবেন না। এই প্রভাবগুলি সারি, ভাগ করা বিশ্বব্যাপী রাষ্ট্র এবং ক্রেপগুলিকে অনেক জায়গায় স্থান দেয়।

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

সামগ্রিকভাবে, যখন রাজ্যের প্রচুর প্রসঙ্গ থাকে তখন কাজগুলি কার্যকর হয়। টাস্কগুলি মূলত পিসি রাষ্ট্রীয় পরিবর্তনশীল হওয়ার সাথে সাথে রাষ্ট্রীয় মেশিন।

একটি মাইক্রোকে করণীয় অনেকগুলি ঘটনার সেটগুলির প্রতিক্রিয়া হিসাবে প্রকাশ করা যেতে পারে। ফলস্বরূপ, আমার সাধারণত একটি প্রধান ইভেন্ট লুপ থাকে। এটি প্রতিটি সম্ভাব্য ইভেন্টটি ধারাবাহিকভাবে পরীক্ষা করে, তারপরে আবার উপরে উঠে যায় এবং এটি আবারও করে। কোনও ইভেন্ট হ্যান্ডেল করার সময় কয়েকটি চক্রের চেয়ে বেশি সময় নেয়, আমি সাধারণত ইভেন্টটি পরিচালনা করার পরে ইভেন্ট লুপের শুরুতে ফিরে যাই। এর ফলস্বরূপ এর অর্থ ইভেন্টগুলিকে তালিকায় কোথায় চেক করা হয়েছে তার ভিত্তিতে একটি অন্তর্নিহিত অগ্রাধিকার রয়েছে have অনেকগুলি সাধারণ সিস্টেমে এটি যথেষ্ট ভাল।

কখনও কখনও আপনি আরও কিছু জটিল কাজ পেতে। এগুলি প্রায়শই পৃথক কিছু সংখ্যক পৃথক কাজের ক্রমে বিভক্ত হতে পারে। আপনি এই ক্ষেত্রে ইভেন্ট হিসাবে অভ্যন্তরীণ পতাকা ব্যবহার করতে পারেন। আমি নিম্ন প্রান্তের পিআইসিগুলিতে এই ধরণের জিনিসটি বহুবার করেছি।

যদি আপনার উপরের মত বেসিক ইভেন্ট স্ট্রাকচার থাকে তবে ইউআরটি দিয়ে একটি কমান্ড স্ট্রিমকেও প্রতিক্রিয়া জানাতে হয়, উদাহরণস্বরূপ, তাহলে প্রাপ্ত ইউআরটি স্ট্রিমটি হ্যান্ডেল করার জন্য একটি পৃথক টাস্ক থাকা কার্যকর। কিছু মাইক্রোকন্ট্রোলারগুলির কাছে PIC 16 এর মতো মাল্টি-টাস্কিংয়ের জন্য সীমিত হার্ডওয়্যার রিসোর্স রয়েছে যা নিজের কল স্ট্যাকটি পড়তে বা লিখতে পারে না। এই জাতীয় ক্ষেত্রে, আমি ইউআআআআরટી কমান্ড প্রসেসরের জন্য সিউডো-টাস্ককে যা বলেছি তা ব্যবহার করি। মূল ইভেন্টের লুপটি এখনও অন্য সমস্ত কিছু পরিচালনা করে তবে হ্যান্ডেল করার জন্য এর একটি ইভেন্ট হ'ল ইউআআআরটি একটি নতুন বাইট পেয়েছিল। সেক্ষেত্রে এটি একটি রুটিনে ঝাঁপিয়ে পড়ে যা এই সিডো-টাস্কটি চালায়। ইউআআআআরટી কমান্ড মডিউলটিতে টাস্ক কোড রয়েছে এবং কার্য সম্পাদনের ঠিকানা এবং টাস্কের কয়েকটি রেজিস্টার মানগুলি সেই মডিউলটিতে র‌্যামে সংরক্ষিত হয়। কোডটি ইভেন্ট লুপটি দিয়ে লাফিয়ে বর্তমান রেজিস্টারগুলি সংরক্ষণ করে, সংরক্ষিত টাস্ক রেজিস্টারগুলি লোড করে, এবং টাস্ক পুনঃসূচনা ঠিকানায় লাফ দেয়। কার্য কোডটি একটি YIELD ম্যাক্রোকে অনুরোধ করে যা বিপরীত হয়, যা পরে শেষ পর্যন্ত মূল ইভেন্ট লুপটির শুরুতে ফিরে আসে। কিছু ক্ষেত্রে মূল ইভেন্ট লুপটি একবার পাসের ক্ষেত্রে সিউডো-টাস্কটি চালায়, সাধারণত এটি নীচের দিকে এটিকে একটি নিম্ন অগ্রাধিকার ইভেন্ট হিসাবে তৈরি করে।

18 এবং ততোধিক একটি পিআইসিতে, কল স্ট্যাকটি ফার্মওয়্যারের দ্বারা পাঠযোগ্য এবং লিখনযোগ্য হওয়ায় আমি একটি সত্য সমবায় টাস্কিং সিস্টেম ব্যবহার করি। এই সিস্টেমে, পুনরায় চালু ঠিকানা, কয়েকটি টুকরো টুকরো রাজ্য এবং ডেটা স্ট্যাক পয়েন্টার প্রতিটি কাজের জন্য একটি মেমরি বাফারে রাখা হয়। অন্য সমস্ত কাজ একবারে চালাতে, একটি টাস্ক TASK_YIELD কল করে। এটি বর্তমান টাস্কের অবস্থাটি সংরক্ষণ করে, পরবর্তী উপলভ্য টাস্কের তালিকার মধ্য দিয়ে দেখায়, তার অবস্থা লোড করে, তারপরে চালায়।

এই আর্কিটেকচারে, লুপের শীর্ষে TASK_YIELD এ কল করে মূল ইভেন্ট লুপটি অন্য একটি কাজ।

পিআইসির জন্য আমার সমস্ত মাল্টি-টাসিং কোডটি বিনামূল্যে পাওয়া যায়। এটি দেখতে, পিআইসি বিকাশ সরঞ্জামগুলি রিলিজটি http://www.ebrainc.com/pic/dload.htm এ ইনস্টল করুন । 8 বিট PICs এর জন্য SOURCE> PIC ডিরেক্টরিতে এবং 16 বিট PICs এর জন্য উত্স> DSPIC ডিরেক্টরিতে "টাস্ক" যুক্ত ফাইলগুলি সন্ধান করুন।


সমবায় মাল্টিটাস্ক সিস্টেমে এখনও মিটেক্সগুলি প্রয়োজনীয় হতে পারে, যদিও এটি বিরল। সাধারণ উদাহরণটি একটি আইএসআর যা একটি সমালোচনামূলক বিভাগে অ্যাক্সেস প্রয়োজন। সমালোচনামূলক তথ্যের জন্য আরও ভাল ডিজাইন বা উপযুক্ত ডেটা ধারক চয়ন করার মাধ্যমে এটি প্রায় সর্বদা এড়ানো যায়।
akohlsmith

@ ইয়াকোহ: হ্যাঁ, আমি এসপিআই বাসে অ্যাক্সেসের মতো ভাগ করা সংস্থানগুলি পরিচালনা করার জন্য কয়েকবার মুটিেক্স ব্যবহার করেছি। আমার বক্তব্যটি ছিল যে মুটেক্সগুলি প্রাক-উদ্দীপনা ব্যবস্থায় তাদের তত পরিমাণে অন্তর্নিহিতভাবে প্রয়োজন হয় না। আমি বলতে চাইছি না যে এগুলি কখনই কোনও সমবায় ব্যবস্থায় প্রয়োজন হয় না বা কখনও ব্যবহৃত হয় না। এছাড়াও, একটি সমবায় সিস্টেমের মধ্যে একটি মিটেক্স একটি টাস্ক_ওয়াইএলডি লুপে স্পিনিং করার মতোই সহজ হতে পারে a প্রাক-কার্যকর পদ্ধতিতে এগুলি সাধারণত কার্নেলের মধ্যে তৈরি করা দরকার।
অলিন ল্যাথ্রপ

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

... তাত্ক্ষণিকভাবে কতগুলি ডেটা লেখা যেতে পারে তা পরীক্ষা করার একটি পদ্ধতি এবং কিছু পরিমাণ উপলব্ধ রয়েছে তা নিশ্চিত করার জন্য একটি পদ্ধতি (যা সম্ভবত ফলন হতে পারে) (নোংরা ফ্ল্যাশ ব্লকগুলির পুনরুদ্ধার ত্বরান্বিত করা এবং একটি উপযুক্ত সংখ্যা পুনরুদ্ধার হওয়া পর্যন্ত অপেক্ষা করা) ।
ক্যাট

হাই ওলিন, আপনার উত্তরটি আমি খুব পছন্দ করি। এর তথ্য আমার প্রশ্নের বহুদূর। এটি ব্যবহারিক অভিজ্ঞতা প্রচুর অন্তর্ভুক্ত।
ইলিশ

1

সম্পাদনা: (আমি আমার আগের পোস্টটি নীচে ছেড়ে দেব; সম্ভবত এটি কোনও দিন কাউকে সহায়তা করবে))

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

আমি খুব সহজ প্রোগ্রাম স্ট্রাকচার যার পটভূমি লুপ শুধু একটি অলস লুপ দেখেছি | for(;;){ ; }। সমস্ত কাজ টাইমার আইএসআর-এ হয়েছিল। প্রোগ্রামটি যখন এমন কিছু ধ্রুবক ক্রিয়াকলাপ পুনরাবৃত্তি করা দরকার যা টাইমার সময়কালের চেয়ে কম সময়ে শেষ করার গ্যারান্টিযুক্ত থাকে তখন এটি কাজ করতে পারে; কিছু নির্দিষ্ট সীমিত সংকেত প্রসেসিং মনে আসে।

ব্যক্তিগতভাবে, আমি আইএসআরগুলি লিখি যা একটি আউট আউট পরিষ্কার করে, এবং ব্যাকগ্রাউন্ডে অন্য যে কোনও কাজ করার দরকার পড়তে দেয়, এমনকি যদি এটি বহুগুনের মতো সহজ হয় এবং এটি টাইমার পিরিয়ডের একটি ভগ্নাংশেও করা যায় add কেন? কোনও দিন, আমি আমার প্রোগ্রামে আরও একটি "সাধারণ" ফাংশন যুক্ত করার উজ্জ্বল ধারণাটি পেয়ে যাব, এবং "হেক, এটি করার জন্য এটি কেবল একটি সংক্ষিপ্ত আইএসআর নেবে" এবং হঠাৎ আমার পূর্বের সহজ স্থাপত্যটি কিছু পরিকল্পনার জন্ম দেয় যা আমি পরিকল্পনা করি নি চালু এবং অসম্পূর্ণভাবে ঘটে। এগুলি ডিবাগ করতে খুব মজাদার নয়।


(পূর্বে দুই ধরণের মাল্টি-টাস্কিংয়ের তুলনায় পোস্ট করা)

কার্য স্যুইচিং: কোনও থ্রেড সিপিইউ-অনাহারিত না হয় এবং উচ্চ-অগ্রাধিকারের থ্রেডগুলি প্রস্তুত হওয়ার সাথে সাথেই চালানো হবে তা সহ প্রি-এম্পিটিভ এমটি আপনার পক্ষে টাস্ক স্যুইচিংয়ের যত্ন নেয়। কো-অপারেটিভ এমটি প্রোগ্রামারকে এটি নিশ্চিত করার জন্য প্রয়োজনীয় যে কোনও থ্রেড প্রসেসরকে একবারে খুব বেশি সময়ের জন্য রাখে না। আপনাকে আরও সিদ্ধান্ত নিতে হবে কত দীর্ঘ কত দীর্ঘ। এর অর্থ এর অর্থ হ'ল আপনি যখনই কোডটি সংশোধন করবেন তখন আপনাকে কোনও কোড বিভাগটি সেই সময়-কোয়ান্টামের চেয়ে বেশি কিনা সে সম্পর্কে সচেতন হওয়া দরকার to

অ-পারমাণবিক ক্রিয়াকলাপ রক্ষা করা: একটি পিএমটি দিয়ে, আপনাকে নিশ্চিত করতে হবে যে অপারেটিংয়ের মাঝখানে থ্রেডের অদলবদলগুলি ঘটবে না যা ভাগ করা উচিত নয়। নির্দিষ্ট ডিভাইস-রেজিস্টার জোড়গুলি পড়া / লেখার জন্য যা অবশ্যই নির্দিষ্ট ক্রমে বা সর্বাধিক সময়ের মধ্যে হ্যান্ডেল করা আবশ্যক। সিএমটি দিয়ে এটি বেশ সহজ - এই জাতীয় অপারেশনের মাঝখানে কেবল প্রসেসরটি উত্পন্ন করবেন না।

ডিবাগিং: সাধারণত সিএমটি-র সাথে সহজ, যেহেতু আপনি যখন / কোথায় থ্রেড স্যুইচগুলি ঘটবে তা পরিকল্পনা করছেন। পিএমটি-র সাথে থ্রেড এবং নিরাপদ অপারেশন সম্পর্কিত থ্রেড এবং বাগগুলির মধ্যে রেসের শর্তগুলি বিশেষভাবে ডিবাগ করা শক্ত কারণ থ্রেডের পরিবর্তনগুলি সম্ভাব্য, তাই পুনরাবৃত্তিযোগ্য নয়।

কোডটি বোঝা: পিএমটি-র জন্য লেখা থ্রেডগুলি অনেকটা এমনভাবে লেখা হয় যেন তারা একা দাঁড়িয়ে থাকতে পারে। সিএমটি-র জন্য লেখা থ্রেডগুলি সেগমেন্ট হিসাবে লেখা হয় এবং আপনার চয়ন করা প্রোগ্রাম কাঠামোর উপর নির্ভর করে পাঠককে অনুসরণ করা শক্ত হতে পারে।

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

একটি যান্ত্রিক ডিভাইস এবং / অথবা বাহ্যিক ইভেন্টগুলি ট্র্যাক করার জন্য একটি সসীম রাষ্ট্র মেশিন-চালিত সিস্টেম সিএমটি-র পক্ষে প্রায়শই ভাল প্রার্থী হয়, যেহেতু প্রতিটি অনুষ্ঠানেই খুব বেশি কিছু করার দরকার নেই - একটি মোটর শুরু করা বা থামানো, একটি পতাকা সেট, পরবর্তী রাষ্ট্রটি বেছে নিন , ইত্যাদি। সুতরাং, রাষ্ট্র-পরিবর্তন কার্যগুলি অন্তর্নিহিত সংক্ষিপ্ত হয় are

একটি হাইব্রিড পদ্ধতির এই ধরণের সিস্টেমে সত্যই কার্যকরভাবে কাজ করতে পারে: স্টেট মেশিন পরিচালনা করার জন্য সিএমটি (এবং তাই বেশিরভাগ হার্ডওয়্যার) একটি থ্রেড হিসাবে চলমান, এবং আরও একটি বা দুটি থ্রেড আর চালিত গণনাগুলি কোনও রাষ্ট্র দ্বারা প্রহার করা যায় পরিবর্তন.


আপনার জবাবের জন্য ধন্যবাদ, জে রবার্ট। তবে এটি আমার প্রশ্নের সাথে মানানসই নয়। এটি প্রিমিপটিভ ওএস বনাম বনামহীন প্রাক-পূর্ববর্তী ওএস এর সাথে তুলনা করে তবে এটি প্রি-প্রিমিটিভ ওএস বনাম নন-ওএসের তুলনা করে না।
হাইল্যাং

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