লিনাক্স / বিএসডি-তে কেন জেনেরিক ব্যাচিংয়ের সিস্টাল নেই?


17

পটভূমি:

সিস্টেম কল ওভারহেড ফাংশন কল ওভারহেডের তুলনায় অনেক বড় (আনুমানিক 20-100x হতে পারে) ব্যবহারকারী স্থান থেকে কার্নেল স্পেস এবং পিছনে প্রসঙ্গে স্যুইচ করার কারণে to ফাংশন কল ওভারহেড সংরক্ষণ করার জন্য ইনলাইন ফাংশনগুলি সাধারণ এবং সিস্কলগুলির চেয়ে ফাংশন কলগুলি অনেক সস্তা। এটি যুক্তিতে দাঁড়ায় যে বিকাশকারীরা একটি সিস্টেমে যতটা সম্ভব ইন-কার্নেল অপারেশন যত্ন নিয়ে সিস্টেম কল ওভারহেডের কিছু এড়াতে চান।

সমস্যা:

এই (? অপর্যাপ্ত) -এর মত সিস্টেম কল অনেকটা সৃষ্টি করেছেন sendmmsg () , recvmmsg () : ভাল chdir, খোলা, lseek এবং / অথবা মত সিমবলিক লিঙ্ক সমন্বয় হিসাবে হিসাবে openat, mkdirat, mknodat, fchownat, futimesat, newfstatat, unlinkat, fchdir, ftruncate, fchmod, renameat, linkat, symlinkat, readlinkat, fchmodat, faccessat, lsetxattr, fsetxattr, execveat, lgetxattr, llistxattr, lremovexattr, fremovexattr, flistxattr, fgetxattr, pread, pwriteইত্যাদি ...

এখন লিনাক্স যুক্ত করেছে copy_file_range()যা আপাতদৃষ্টিতে লিডিক রিড এবং সিস্কল লেখার সংমিশ্রণ করেছে । এটি fcopy_file_range (), lcopy_file_range (), copy_file_rangeat (), fcopy_file_rangeat () এবং lcopy_file_rangeat () হয়ে ওঠার আগে এটি কেবল সময়ের বিষয় ... তবে যেহেতু এক্স আরও কলগুলির পরিবর্তে 2 টি ফাইল জড়িত রয়েছে, তাই এটি এক্স 2-এ পরিণত হতে পারে আরও অনেক কিছু। ঠিক আছে, লিনাস এবং বিভিন্ন বিএসডি বিকাশকারীরা এটিকে এতদূর যেতে দেয় না, তবে আমার বক্তব্যটি হ'ল যদি কোনও ব্যাচিং সিস্কেল থাকত তবে এগুলির সমস্ত (বেশিরভাগ?) ব্যবহারকারীর জায়গায় প্রয়োগ করা যেতে পারে এবং বেশি কিছু না যুক্ত করে কার্নেলের জটিলতা হ্রাস করতে পারে যদি libc দিকে কোনও ওভারহেড থাকে।

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

সমাধান ?:

একটি জেনেরিক ব্যাচিং সিস্টেল। এটি বিশেষায়িত কার্নেল থ্রেডের সাথে সম্পর্কিত জটিলতা ছাড়াই সবচেয়ে বড় ব্যয় (একাধিক মোড স্যুইচ) হ্রাস করতে পারে (যদিও সেই কার্যকারিতাটি পরে যুক্ত করা যেতে পারে)।

সকেটকল () সিস্কেলটিতে মূলত প্রোটোটাইপের জন্য ইতিমধ্যে একটি ভাল ভিত্তি রয়েছে। পরিবর্তে আর্গুমেন্টের অ্যারে নেওয়া থেকে এটির পরিবর্তে প্রসারিত করুন, রিটার্নের অ্যারে নিতে পয়েন্টার, আর্গুমেন্টের অ্যারেগুলিতে পয়েন্টার (যার মধ্যে সিস্কাল নম্বর অন্তর্ভুক্ত), সাইককলের সংখ্যা এবং একটি পতাকা আর্গুমেন্ট ... এর মতো কিছু:

batch(void *returns, void *args, long ncalls, long flags);

একটি প্রধান পার্থক্য হ'ল আর্গুমেন্টগুলি সম্ভবত সমস্ত সরলতার জন্য পয়েন্টার হওয়া দরকার যাতে পূর্ববর্তী সাইকেলের ফলাফলগুলি পরবর্তী সিস্টেমে ব্যবহার করা যেতে পারে (উদাহরণস্বরূপ / ফাইলের open()জন্য ফাইল বর্ণনাকারী read()/ ব্যবহারের জন্য write())

কিছু সম্ভাব্য সুবিধা:

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

প্রশ্ন:

একটি ব্যাচিং সিস্টেমটি বাস্তবায়িত করা কি সম্ভব?

  • আমি কি কিছু সুস্পষ্ট গোটাচা মিস করছি?
  • আমি কি সুবিধাগুলি অত্যধিক বিবেচনা করছি?

ব্যাচিং সিস্কেল (আমি ইন্টেল, গুগল বা রেডহ্যাটে কাজ করি না) বাস্তবায়নে বিরক্ত করা কি আমার পক্ষে সার্থক?

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

তথ্যসূত্র:


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

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

1
সিস্কলগুলিতে একটি বিশেষাধিকারের পরিবর্তন জড়িত তবে এটি সর্বদা প্রসঙ্গে স্যুইচ হিসাবে চিহ্নিত হয় না। en.wikedia.org/wiki/…
এরিক tদ

1
গতকাল এটি পড়ুন যা আরও কিছু অনুপ্রেরণা এবং পটভূমি সরবরাহ করে: matildah.github.io/posts/2016-01-30-unikernel-security.html
টম

@ জার্গডাব্লু মিটাটাগ নেস্টালকে কার্নেল স্ট্যাকের ওভারফ্লো থেকে রোধ করতে নিষেধ করা যেতে পারে। অন্যথায়, পৃথক সিস্কেলগুলি সাধারণত তারা যেমন করে তাদের পরে ফ্রি হবে। এটির সাথে কোনও সংস্থান-হগিংয়ের সমস্যা হওয়া উচিত নয়। লিনাক্স কার্নেল প্রিমিটেবল।
পিএসকোকিক

উত্তর:


5

আমি x86_64 এ চেষ্টা করেছিলাম

94836ecf1e7378b64d37624fbb81fe48fbd4c772 এর বিরুদ্ধে প্যাচ: (এছাড়াও এখানে https://github.com/pskocik/linux/tree/supersyscall )

diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 5aef183e2f85..8df2e98eb403 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -339,6 +339,7 @@
 330    common  pkey_alloc      sys_pkey_alloc
 331    common  pkey_free       sys_pkey_free
 332    common  statx           sys_statx
+333    common  supersyscall            sys_supersyscall

 #
 # x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 980c3c9b06f8..c61c14e3ff4e 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -905,5 +905,20 @@ asmlinkage long sys_pkey_alloc(unsigned long flags, unsigned long init_val);
 asmlinkage long sys_pkey_free(int pkey);
 asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags,
              unsigned mask, struct statx __user *buffer);
-
 #endif
+
+struct supersyscall_args {
+    unsigned call_nr;
+    long     args[6];
+};
+#define SUPERSYSCALL__abort_on_failure    0
+#define SUPERSYSCALL__continue_on_failure 1
+/*#define SUPERSYSCALL__lock_something    2?*/
+
+
+asmlinkage 
+long 
+sys_supersyscall(long* Rets, 
+                 struct supersyscall_args *Args, 
+                 int Nargs, 
+                 int Flags);
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index a076cf1a3a23..56184b84530f 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -732,9 +732,11 @@ __SYSCALL(__NR_pkey_alloc,    sys_pkey_alloc)
 __SYSCALL(__NR_pkey_free,     sys_pkey_free)
 #define __NR_statx 291
 __SYSCALL(__NR_statx,     sys_statx)
+#define __NR_supersyscall 292
+__SYSCALL(__NR_supersyscall,     sys_supersyscall)

 #undef __NR_syscalls
-#define __NR_syscalls 292
+#define __NR_syscalls (__NR_supersyscall+1)

 /*
  * All syscalls below here should go away really,
diff --git a/init/Kconfig b/init/Kconfig
index a92f27da4a27..25f30bf0ebbb 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -2184,4 +2184,9 @@ config ASN1
      inform it as to what tags are to be expected in a stream and what
      functions to call on what tags.

+config SUPERSYSCALL
+     bool
+     help
+        System call for batching other system calls
+
 source "kernel/Kconfig.locks"
diff --git a/kernel/Makefile b/kernel/Makefile
index b302b4731d16..4d86bcf90f90 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -9,7 +9,7 @@ obj-y     = fork.o exec_domain.o panic.o \
        extable.o params.o \
        kthread.o sys_ni.o nsproxy.o \
        notifier.o ksysfs.o cred.o reboot.o \
-       async.o range.o smpboot.o ucount.o
+       async.o range.o smpboot.o ucount.o supersyscall.o

 obj-$(CONFIG_MULTIUSER) += groups.o

diff --git a/kernel/supersyscall.c b/kernel/supersyscall.c
new file mode 100644
index 000000000000..d7fac5d3f970
--- /dev/null
+++ b/kernel/supersyscall.c
@@ -0,0 +1,83 @@
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <linux/compiler.h>
+#include <linux/sched/signal.h>
+
+/*TODO: do this properly*/
+/*#include <uapi/asm-generic/unistd.h>*/
+#ifndef __NR_syscalls
+# define __NR_syscalls (__NR_supersyscall+1)
+#endif
+
+#define uif(Cond)  if(unlikely(Cond))
+#define lif(Cond)  if(likely(Cond))
+ 
+
+typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,
+                     unsigned long, unsigned long,
+                     unsigned long, unsigned long);
+extern const sys_call_ptr_t sys_call_table[];
+
+static bool 
+syscall__failed(unsigned long Ret)
+{
+   return (Ret > -4096UL);
+}
+
+
+static bool
+syscall(unsigned Nr, long A[6])
+{
+    uif (Nr >= __NR_syscalls )
+        return -ENOSYS;
+    return sys_call_table[Nr](A[0], A[1], A[2], A[3], A[4], A[5]);
+}
+
+
+static int 
+segfault(void const *Addr)
+{
+    struct siginfo info[1];
+    info->si_signo = SIGSEGV;
+    info->si_errno = 0;
+    info->si_code = 0;
+    info->si_addr = (void*)Addr;
+    return send_sig_info(SIGSEGV, info, current);
+    //return force_sigsegv(SIGSEGV, current);
+}
+
+asmlinkage long /*Ntried*/
+sys_supersyscall(long* Rets, 
+                 struct supersyscall_args *Args, 
+                 int Nargs, 
+                 int Flags)
+{
+    int i = 0, nfinished = 0;
+    struct supersyscall_args args; /*7 * sizeof(long) */
+    
+    for (i = 0; i<Nargs; i++){
+        long ret;
+
+        uif (0!=copy_from_user(&args, Args+i, sizeof(args))){
+            segfault(&Args+i);
+            return nfinished;
+        }
+
+        ret = syscall(args.call_nr, args.args);
+        nfinished++;
+
+        if ((Flags & 1) == SUPERSYSCALL__abort_on_failure 
+                &&  syscall__failed(ret))
+            return nfinished;
+
+
+        uif (0!=put_user(ret, Rets+1)){
+            segfault(Rets+i);
+            return nfinished;
+        }
+    }
+    return nfinished;
+
+}
+
+
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 8acef8576ce9..c544883d7a13 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -258,3 +258,5 @@ cond_syscall(sys_membarrier);
 cond_syscall(sys_pkey_mprotect);
 cond_syscall(sys_pkey_alloc);
 cond_syscall(sys_pkey_free);
+
+cond_syscall(sys_supersyscall);

এবং এটি কাজ করে বলে মনে হচ্ছে - আমি হ্যালো লিখতে পারি এফডি 1 এবং ওয়ার্ল্ড এফডি 2 তে মাত্র একটি সিস্কেল দিয়ে:

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>


struct supersyscall_args {
    unsigned  call_nr;
    long args[6];
};
#define SUPERSYSCALL__abort_on_failure    0
#define SUPERSYSCALL__continue_on_failure 1

long 
supersyscall(long* Rets, 
                 struct supersyscall_args *Args, 
                 int Nargs, 
                 int Flags);

int main(int c, char**v)
{
    puts("HELLO WORLD:");
    long r=0;
    struct supersyscall_args args[] = { 
        {SYS_write, {1, (long)"hello\n", 6 }},
        {SYS_write, {2, (long)"world\n", 6 }},
    };
    long rets[sizeof args / sizeof args[0]];

    r = supersyscall(rets, 
                     args,
                     sizeof(rets)/sizeof(rets[0]), 
                     0);
    printf("r=%ld\n", r);
    printf( 0>r ? "%m\n" : "\n");

    puts("");
#if 1

#if SEGFAULT 
    r = supersyscall(0, 
                     args,
                     sizeof(rets)/sizeof(rets[0]), 
                     0);
    printf("r=%ld\n", r);
    printf( 0>r ? "%m\n" : "\n");
#endif
#endif
    return 0;
}

long 
supersyscall(long* Rets, 
                 struct supersyscall_args *Args, 
                 int Nargs, 
                 int Flags)
{
    return syscall(333, Rets, Args, Nargs, Flags);
}

মূলত আমি ব্যবহার করছি:

long a_syscall(long, long, long, long, long, long);

একটি ইউনিভার্সাল সিস্কেল প্রোটোটাইপ হিসাবে, যা x86_64 এ জিনিসগুলি কীভাবে কাজ করে তা দেখা যায়, তাই আমার "সুপার" সিস্টেমটি হ'ল:

struct supersyscall_args {
    unsigned call_nr;
    long     args[6];
};
#define SUPERSYSCALL__abort_on_failure    0
#define SUPERSYSCALL__continue_on_failure 1
/*#define SUPERSYSCALL__lock_something    2?*/

asmlinkage 
long 
sys_supersyscall(long* Rets, 
                 struct supersyscall_args *Args, 
                 int Nargs, 
                 int Flags);

এটি চেষ্টা করা সিস্কলগুলির সংখ্যা প্রদান করে ( ==Nargsযদি SUPERSYSCALL__continue_on_failureপতাকাটি পাস করা হয়, অন্যথায় >0 && <=Nargs) এবং কার্নেল স্পেস এবং ব্যবহারকারীর স্থানের মধ্যে অনুলিপি ব্যর্থতা স্বাভাবিকের পরিবর্তে সেগফাল্টস দ্বারা চিহ্নিত করা হয় -EFAULT

যা আমি জানি না এটি অন্যান্য আর্কিটেকচারের কাছে কীভাবে পোর্ট হবে, তবে কার্নেলের মধ্যে এটির মতো কিছু পাওয়া নিশ্চিত হবে।

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


1
তার ধারণা একটি ভাল প্রমাণ, যদিও আমি শুধু দীর্ঘ একটি অ্যারের দীর্ঘ পরিবর্তে পয়েন্টার একটি অ্যারের দেখতে তোমার মতোই ওপেন লেখার ঘনিষ্ঠ ফেরত ব্যবহার জিনিস করতে পারে, যাতে চাই openমধ্যে writeএবং close। এটি পেতে / put_user কারণে জটিলতা কিছুটা বাড়িয়ে তুলবে, তবে সম্ভবত এটি মূল্যবান worth আইআইআরসি বহনযোগ্যতা হিসাবে কিছু স্থাপত্য 5 এবং 6 টির জন্য সিস্কল রেজিস্টারগুলি ক্লোবার করতে পারে যদি 5 বা 6 আরগের সিস্কেলটি ব্যাচ করা হয় ... ভবিষ্যতের ব্যবহারের জন্য 2 টি অতিরিক্ত আরোগুলি যুক্ত করা ঠিক করে দেয় এবং ভবিষ্যতে অ্যাসিক্রোনাস কল প্যারামিটারের জন্য ব্যবহার করা যেতে পারে একটি সুপারসাইক্যাল__ ফ্যাসিঙ্ক পতাকা সেট করা হয়েছে
টেকনোসরাস

1
আমার উদ্দেশ্য ছিল একটি সিস_মাম্পিও যুক্ত করা। ব্যবহারকারীরা ইউজারস্পেসে মোডটি স্যুইচ না করেই sys_writ এর প্রথম আর্গুমেন্টে অনুলিপি করা fd অনুলিপি করতে sys_open এবং sys_write এর মধ্যে রেখে দিতে পারেন।
পিএসকোকিক

3

দুটি প্রধান গোটাচা যা তত্ক্ষণাত মনে আসে:

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

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


2
পুনরায়: ত্রুটি পরিচালনা আমি সে সম্পর্কে ভেবেছিলাম এবং সে কারণেই আমি ফ্ল্যাগস আর্গুমেন্টের প্রস্তাব দিয়েছিলাম (BATCH_RET_ON_FIRST_ERR) ... একটি কলম্বিত সিস্টেমে যদি কলগুলি ত্রুটি ছাড়াই সম্পূর্ণ হয় বা যদি কোনও ব্যর্থ হয় তবে শেষ কলস যদি একটি ব্যর্থ হয় তবে এনসিএলগুলি ফিরিয়ে দেওয়া উচিত। এটি আপনাকে ত্রুটিগুলি যাচাই করার অনুমতি দেয় এবং কেবলমাত্র 2 পয়েন্টার বাড়িয়ে এবং রিসোর্স মূল্য দ্বারা এনকোল হ্রাস করে পুনরায় প্রথম ব্যর্থ কল থেকে আবার চেষ্টা করার চেষ্টা করে যদি কোনও উত্স ব্যস্ত থাকে বা কলটি ইন্টারপ্ট হয়। ... প্রসঙ্গবিহীন সুইচিং অংশগুলি এর সুযোগের বাইরে নয়, তবে লিনাক্স ৪.২ থেকে স্প্লাইস ()
সেগুলিও

2
কার্নেলটি বিভিন্ন ক্রিয়াকলাপকে একত্রিত করতে এবং অপ্রয়োজনীয় কাজটি সরিয়ে দিতে স্বয়ংক্রিয়ভাবে কল তালিকাকে অপ্টিমাইজ করতে পারে। সহজ এপিআই দিয়ে প্রচেষ্টায় দুর্দান্ত সঞ্চয়ে সর্বাধিক পৃথক বিকাশকারীদের চেয়ে কার্নেল সম্ভবত আরও ভাল কাজ করবে।
আলেকসান্দ্র ডাবিনস্কি 13

@ টেকনোসরাস এটি কোনও প্রযুক্তি অপারেশন ব্যর্থ হয়েছে তা যোগাযোগ করে এমন প্রযুক্তিবিদদের ধারণার সাথে সামঞ্জস্যপূর্ণ হবে না (কারণ অপারেশনের ক্রমটি অনুকূলিত হয়)। এ কারণেই ব্যতিক্রমগুলি এ জাতীয় সঠিক তথ্য ফেরত দেওয়ার জন্য সাধারণত নকশাকৃত হয় না (এছাড়াও, কারণ কোডটি বিভ্রান্তিকর এবং ভঙ্গুর হয়ে যায়)। ভাগ্যক্রমে, জেনেরিক ব্যতিক্রম হ্যান্ডলারগুলি লিখতে অসুবিধা হয় না যা বিভিন্ন ব্যর্থতা মোডগুলি পরিচালনা করে।
আলেকসান্দ্র ডাবিনস্কি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.