ডি রাজ্যে একটি অগ্রহণযোগ্য প্রক্রিয়া অনুকরণ করুন


14

আউট সার্ভার পরিবেশে বিপর্যয় পরীক্ষার পরিস্থিতিগুলির জন্য আমরা ডি (নিরবচ্ছিন্ন ঘুম) অবস্থায় আটকে একটি প্রক্রিয়া তৈরি করার একটি সহজ উপায় খুঁজছি।

কোন সহজ উপায়? উদাহরণস্বরূপ সি নমুনা কোডটি একটি প্লাস হবে :)

সম্পাদনা করুন - প্রথম উত্তরটি অর্ধ-সঠিক, প্রক্রিয়াটি ডি অবস্থায় রয়েছে বলে দেখানো হলেও এটি এখনও সংকেত পেয়েছে এবং হত্যা করা যেতে পারে



কোন অপারেটিং সিস্টেমে? অথবা আপনি কোনও বহনযোগ্য সমাধানের সন্ধান করছেন (এটি কিনা তা নিশ্চিত নন)?
ডারোবার্ট

@ এমআর_ট্রন - এটি "নিরবচ্ছিন্ন" নয় :)
er453r

1
@डरোবার্ট - সঠিক না হওয়ার জন্য দুঃখিত - উবুন্টু সার্ভার 12.04.4
er453r

1
যারা "কার্যনির্বাহী" সমাধান খুঁজছেন তাদের জন্য stackoverflow.com/a/22754979/2182622
ননাম

উত্তর:


2

আমার একই সমস্যা ছিল এবং এটি ডিফল্ট অবস্থায় আটকে যায় এমন একটি কার্নেল মডিউল তৈরি করে সমাধান করেছি।

আমি মডিউল কোনো অভিজ্ঞতা না থাকে হিসেবে আমি থেকে কোড নেন এই turorial কিছু পরিবর্তন মাল পেয়েছি, এমন একটি স্থানে esle

ফলাফলটি হ'ল / ডিভ / মেমরির এমন একটি ডিভাইস যা পড়তে আটকে যায় তবে তাতে লেখাটি জাগ্রত করা যায় (এর জন্য দুটি লেখার দরকার আছে, আমি জানি না তবে কেন আমি যত্ন করি না)।

এটি কেবল ব্যবহার করতে:

# make
# make mknod
# make install
# cat /dev/memory   # this gets blocked

অন্য টার্মিনাল থেকে অবরোধ মুক্ত করতে:

# echo -n a > /dev/memory
# echo -n a > /dev/memory

Makefile নামক:

obj-m += memory.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

install:
    sudo insmod memory.ko

uninstall:
    sudo rmmod memory

mknod:
    sudo mknod /dev/memory c 60 0
    sudo chmod 666 /dev/memory

মেমরির জন্য কোড:

/* Necessary includes for device drivers */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/uaccess.h> /* copy_from/to_user */
#include <linux/sched.h>

MODULE_LICENSE("Dual BSD/GPL");

/* Declaration of memory.c functions */
int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
void memory_exit(void);
int memory_init(void);

/* Structure that declares the usual file */
/* access functions */
ssize_t memory_write( struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
struct file_operations memory_fops = {
    .read = memory_read,
    .write = memory_write,
    .open = memory_open,
    .release = memory_release
};

/* Declaration of the init and exit functions */
module_init(memory_init);
module_exit(memory_exit);

/* Global variables of the driver */
/* Major number */
int memory_major = 60;
/* Buffer to store data */
char *memory_buffer;

int memory_init(void) {
    int result;

    /* Registering device */
    result = register_chrdev(memory_major, "memory", &memory_fops);
    if (result < 0) {
        printk(
                "<1>memory: cannot obtain major number %d\n", memory_major);
        return result;
    }

    /* Allocating memory for the buffer */
    memory_buffer = kmalloc(1, GFP_KERNEL); 
    if (!memory_buffer) { 
        result = -ENOMEM;
        goto fail; 
    } 
    memset(memory_buffer, 0, 1);

    printk("<1>Inserting memory module\n"); 
    return 0;

fail: 
    memory_exit(); 
    return result;
}

void memory_exit(void) {
    /* Freeing the major number */
    unregister_chrdev(memory_major, "memory");

    /* Freeing buffer memory */
    if (memory_buffer) {
        kfree(memory_buffer);
    }

    printk("<1>Removing memory module\n");

}

int memory_open(struct inode *inode, struct file *filp) {

    /* Success */
    return 0;
}

int memory_release(struct inode *inode, struct file *filp) {

    /* Success */
    return 0;
}
static DECLARE_WAIT_QUEUE_HEAD(wq);
static volatile int flag = 0;

ssize_t memory_read(struct file *filp, char *buf, 
        size_t count, loff_t *f_pos) { 

    printk("<1>going to sleep\n");
    flag = 0;
    //wait_event_interruptible(wq, flag != 0);
    wait_event(wq, flag != 0);

    printk("<1>Reading from memory module\n");
    /* Transfering data to user space */ 
    copy_to_user(buf,memory_buffer,1);

    /* Changing reading position as best suits */ 
    if (*f_pos == 0) { 
        *f_pos+=1; 
        return 1; 
    } else { 
        return 0; 
    }
}

ssize_t memory_write( struct file *filp, char *buf,
        size_t count, loff_t *f_pos) {

    char *tmp;

    printk("<1>wake someone up\n");
    flag = 1;
    //wake_up_interruptible(&wq);
    wake_up(&wq);

    printk("<1>Writting to memory module\n");
    tmp=buf+count-1;
    copy_from_user(memory_buffer,tmp,1);
    return 1;
}

দুর্ভাগ্যক্রমে, উভয় লিঙ্কই মারা গেছে এবং এখানে অনুলিপি করা ফাইলগুলিতে সমস্ত কিছুই নেই।
ডুনাটোটাটোস

10

Https://blogs.oracle.com/ksplice/entry/disown_zombie_children_and_the থেকে

যখন কোনও কিছুর (সাধারণত I / O)(STAT D) অপেক্ষা করার প্রয়োজন হয় তখন একটি প্রক্রিয়া একটি নিরবচ্ছিন্ন ঘুমে রাখা হয় এবং অপেক্ষা করার সময় সংকেতগুলি পরিচালনা করা উচিত নয়। এর অর্থ আপনি এটি পারবেন না , কারণ সমস্ত হত্যাকাণ্ডই এটি সিগন্যাল প্রেরণ করে। অন্যান্য মেশিনের সাথে ওপেন নেটওয়ার্ক সংযোগ থাকা অবস্থায় আপনি যদি আপনার এনএফএস সার্ভারটি প্লাগ লাগান তবে বাস্তব বিশ্বে এটি ঘটতে পারে।kill

আমরা vforkসিস্টেম কলের সুবিধা গ্রহণ করে সীমিত সময়ের জন্য আমাদের নিজস্ব নিরবচ্ছিন্ন প্রক্রিয়া তৈরি করতে পারি । vforkমত fork, ঠিকানার জায়গাগুলি বাদে পিতা-মাতার কাছ থেকে সন্তানের মধ্যে অনুলিপি করা হয় না, এমন একটি প্রত্যাশায় execযা অনুলিপি করা ডেটা ফেলে দেয়। সুবিধামতভাবে আমাদের জন্য, যখন আপনি vforkপিতা-মাতা সন্তানের উপর নিরবচ্ছিন্নভাবে (পথে wait_on_completion) অপেক্ষা করেন execবা exit:

jesstess@aja:~$ cat uninterruptible.c 
int main() {
    vfork();
    sleep(60);
    return 0;
}
jesstess@aja:~$ gcc -o uninterruptible uninterruptible.c
jesstess@aja:~$ echo $$
13291
jesstess@aja:~$ ./uninterruptible
and in another shell:

jesstess@aja:~$ ps -o ppid,pid,stat,cmd $(pgrep -f uninterruptible)

13291  1972 D+   ./uninterruptible
 1972  1973 S+   ./uninterruptible

আমরা বাচ্চাকে ( PID 1973, PPID 1972) PID 1972, PPID 13291একটি অবিচ্ছিন্ন ঘুমে এবং পিতা-মাতা ( - শেল) একটি নিরবচ্ছিন্ন ঘুমে দেখি যখন এটি সন্তানের উপর 60 সেকেন্ড অপেক্ষা করে।

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


ঠিক কী খুঁজছিল! আপনাকে অনেক ধন্যবাদ!
er453r

3
দুঃখজনক বিষয় হ'ল প্রক্রিয়াটি ডি অবস্থায় রয়েছে তবে আমি এটি দিয়ে এটি সক্ষম করতে পেরেছি kill: /
er453r

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

ধন্যবাদ - আপনি যেমন পোস্ট করেছেন ঠিক তেমনই পড়েছি। আমি ইতিমধ্যে এর জন্য ইন্টারনেট অনুসন্ধান করেছি, তবে প্রত্যেকে এই প্রক্রিয়াগুলি থেকে মুক্তি পাওয়ার চেষ্টা করে, সেগুলি তৈরি করে না: পি সাধারণত, স্ট্যাক এক্সচেঞ্জ সর্বদা আমার জন্য সর্বশেষ অবলম্বন :)
er453r

হ্যাঁ, আমি এটিকে এখনও মেরে ফেলতে পারি: - /
লিও উফিম্টসেভ

2

মূলত, আপনি পারবেন না। এই নিবন্ধটি পড়ুন: শিরোনাম: TASK_KILLABLE: লিনাক্সে নতুন প্রক্রিয়া অবস্থা

উদ্ধৃতাংশ

লিনাক্স কার্নেল ২.6.২৫ টি TASK_KILLABLE নামক প্রক্রিয়াগুলিকে স্লিপ করার জন্য একটি নতুন প্রক্রিয়া অবস্থা প্রবর্তন করে, যা দক্ষ কিন্তু সম্ভাব্য অযোগ্য টাস্ক_উইনআিন্টারআরপিটিআইবিএল এবং সহজেই জাগ্রত করতে পারে তবে নিরাপদ TASK_INTERRUPTIBLE এর বিকল্প প্রস্তাব করে।

এই SO প্রশ্নোত্তর শিরোনাম: একটি নিরবচ্ছিন্ন প্রক্রিয়া কী? এটিও ব্যাখ্যা করে

আমি এটি অত্যন্ত আকর্ষণীয় বই শিরোনামে আবিষ্কার করেছি: লিনাক্স প্রোগ্রামিং ইন্টারফেস: একটি লিনাক্স এবং ইউনিক্স সিস্টেম প্রোগ্রামিং হ্যান্ডবুক


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