📜  共享内存中的并发合并排序

📅  最后修改于: 2022-05-13 01:57:08.950000             🧑  作者: Mango

共享内存中的并发合并排序

给定一个数字“n”和一个数字,使用并发合并排序对数字进行排序。 (提示:尝试使用 shmget、shmat 系统调用)。
第 1 部分:算法(如何?)
递归地制作两个子进程,一个用于左半边,一个用于右半边。如果某个进程的数组中的元素数小于 5,则执行插入排序。然后两个孩子的父级合并结果并返回给父级,依此类推。但是你如何让它并发呢?
第 2 部分:逻辑(为什么?)
解决这个问题的重要部分不是算法,而是解释操作系统和内核的概念。
为了实现并发排序,我们需要一种方法让两个进程同时在同一个数组上工作。为了让事情变得更简单,Linux 通过简单的 API 端点提供了许多系统调用。其中两个是shmget() (用于共享内存分配)和shmat() (用于共享内存操作)。我们在我们 fork 的子进程之间创建一个共享内存空间。每个段都分为左右子节点,它们是排序的,有趣的部分是它们同时工作! shmget() 请求内核为两个进程分配一个共享页面。
为什么传统的 fork() 不起作用?
答案在于 fork() 的实际作用。在文档中,“fork() 通过复制调用进程来创建一个新进程”。子进程和父进程在不同的内存空间中运行。在 fork() 时,两个内存空间具有相同的内容。由其中一个进程执行的内存写入、文件描述符(fd)更改等不会影响另一个进程。因此我们需要一个共享内存段。

CPP
// C program to implement concurrent merge sort
#include 
#include 
#include 
#include 
#include 
#include 
 
void insertionSort(int arr[], int n);
void merge(int a[], int l1, int h1, int h2);
 
void mergeSort(int a[], int l, int h)
{
    int i, len=(h-l+1);
 
    // Using insertion sort for small sized array
    if (len<=5)
    {
        insertionSort(a+l, len);
        return;
    }
 
    pid_t lpid,rpid;
    lpid = fork();
    if (lpid<0)
    {
        // Lchild proc not created
        perror("Left Child Proc. not created\n");
        _exit(-1);
    }
    else if (lpid==0)
    {
        mergeSort(a,l,l+len/2-1);
        _exit(0);
    }
    else
    {
        rpid = fork();
        if (rpid<0)
        {
            // Rchild proc not created
            perror("Right Child Proc. not created\n");
            _exit(-1);
        }
        else if(rpid==0)
        {
            mergeSort(a,l+len/2,h);
            _exit(0);
        }
    }
 
    int status;
 
    // Wait for child processes to finish
    waitpid(lpid, &status, 0);
    waitpid(rpid, &status, 0);
 
    // Merge the sorted subarrays
    merge(a, l, l+len/2-1, h);
}
 
/* Function to sort an array using insertion sort*/
void insertionSort(int arr[], int n)
{
   int i, key, j;
   for (i = 1; i < n; i++)
   {
       key = arr[i];
       j = i-1;
 
       /* Move elements of arr[0..i-1], that are
          greater than key, to one position ahead
          of their current position */
       while (j >= 0 && arr[j] > key)
       {
           arr[j+1] = arr[j];
           j = j-1;
       }
       arr[j+1] = key;
   }
}
 
// Method to merge sorted subarrays
void merge(int a[], int l1, int h1, int h2)
{
    // We can directly copy  the sorted elements
    // in the final array, no need for a temporary
    // sorted array.
    int count=h2-l1+1;
    int sorted[count];
    int i=l1, k=h1+1, m=0;
    while (i<=h1 && k<=h2)
    {
        if (a[i]


输出:

Sorting Done Successfully