共享内存中的并发合并排序
给定一个数字“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