【问题标题】:Sorting 1 Million Integers Using Threads in Windows在 Windows 中使用线程对 100 万个整数进行排序
【发布时间】:2018-08-30 19:40:34
【问题描述】:

我有一个任务是用 C 编程语言(在 Windows 平台上)使用 8 线程对 100 万个随机整数进行排序。

  1. 我必须创建一个包含 100 万个随机整数的二进制文件。 (完成)
  2. 我必须将这些整数缓冲到一个数组中。 (完成)
  3. 我必须创建 8 个线程。 (完成)每个线程取 1/8 的数组并对其进行排序(算法可以是合并或快速排序)。
  4. 然后合并所有子数组,构造一个完全排序好的数组。

Here's a detailed description for threads.

我正在 Visual Studio 2017 上编写代码,这是我的进度:

// 1MRandomNumber.cpp : Defines the entry point for the console application.
//    
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "windows.h"
#include "time.h"
#include <tchar.h>
#include <strsafe.h>

#define MAX_THREADS 8

static int numbers[1000000];

DWORD WINAPI QuickSort(LPVOID lpParam);

//Creating a File with 1000000 random integers;
void create1MBinaryFile(){
    int i, x;
    FILE *fp = fopen("1MRandomNumbers.dat","wb");
    srand(time(NULL));
    for (i = 0; i<1000000; i++) {
        x = (rand() * rand()) % 1000001;
        fprintf(fp,"%d \n", x);
    }
    fclose(fp);
    printf("File is created\n");
}

//Buffers integers to "numbers" Array;
void loadFiletoArray() {
    int i = 0;
    char buf[128];
    FILE *fp = fopen("1MRandomNumbers.dat", "rb");
    if (fp == NULL) {
        fprintf(stderr, "Error in opening file");
        exit(1);
    }

    for (int i = 0; i < 1000000 - 1; i++) {
        fgets(buf, sizeof(buf), fp);
        sscanf_s(buf, "%d", &numbers[i]);
    }
    fclose(fp);
    printf("Numbers loaded to an array\n");
}

//Creates 8 Threads
void threadCreate() {
    DWORD   dwThreadIdArray[MAX_THREADS];
    HANDLE  hThreadArray[MAX_THREADS];

    for (int i = 0; i<MAX_THREADS -1; i++)
    {
        hThreadArray[i] = CreateThread(
            NULL,          
            0,                    
            QuickSort,      
            NULL,         
            0,                     
            &dwThreadIdArray[i]);   
        printf("Thread %d created \n", dwThreadIdArray[i]);
    } 

    WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);

    for (int i = 0; i<MAX_THREADS; i++)
    {
        CloseHandle(hThreadArray[i]);
    }
}

int main(int argv, char *argc[])
{
    create1MBinaryFile();
    loadFiletoArray();
    threadCreate();

    return 0;
}

DWORD WINAPI QuickSort(LPVOID lpParam) {

    return 0;
}

那么如何在 Windows 平台上创建多线程。在我们的讲座中,我们已经学会了在 POSIX 库中做到这一点,但我想了解如何使用 Windows 线程来实现它。

编辑:我创建了8 线程。这是一种真正的方法还是我应该改变它?另外,如何为每个线程拆分数组并对其进行快速排序?

【问题讨论】:

  • pthreads 库有一个 Windows 实现,应该有助于不必重写代码。谷歌可以为您找到它。如果它必须是特定于 Windows 的练习,那么 Google 也知道这一点,请查询“windows 如何创建线程”。
  • 这可能是一个不错的起点,但您似乎通过使用新的 API 而不是您在讲座中熟悉的 API 给自己增加了额外的负担:msdn.microsoft.com/en-us/library/y6h8hye8.aspx
  • @HansPassant 这不是特定于 Windows 的,但我只想在 Windows 中学习它。我做了一些研究,并阅读了一些关于微软的文章。但我无法理解这个概念。特别是在这个示例代码中:link
  • 请注意,由于每个线程将管理数组的 1/8,因此恕我直言,在数组中没有用于读取/写入的互斥锁是安全的。
  • @Tom 感谢我注意到它的评论。但我也没有看到使用互斥锁的理由。我可以不使用互斥锁来实现它。

标签: c windows multithreading sorting


【解决方案1】:

代码看起来没问题,只是它创建了 7 个线程 (MAX_THREADS-1) 然后等待 8 个线程。此外,代码应该使用 lpParameter 作为指向结构的指针,该结构指定要由线程排序的数组的 1/8,它可以是一对指针(开始和结束指针)或索引。代码应该在启动线程之前将整个文件读入数组。

要将数组拆分为 8 个部分,则每个 1/8 的大小 = array_size / 8,最后 1/8 比其他的大(最多大 7 个)。如果你想要更均匀的分割,让remainder = array_size % 8。然后第一个 remainder 线程的大小为 (array_size / 8) + 1,其余线程的大小为 (array_size / 8)。

可选 - 您可以使用线程进行合并。将线程编号为 0 到 7,然后线程 6 可以等待线程 7 退出,然后合并部分 6 和 7。线程 4 可以等待线程 5,合并部分 4 和 5,然后等待线程 6,然后合并合并的 4 ,5 和 6,7 等等。我不确定这会比单线程 8 路合并快得多。

【讨论】:

  • 感谢您的回复。当您说代码时,您的意思是“CreateThread”部分?在第三个“”之后,我写了“NULL”?如果是这样,如果它采用 LPVOID 类型,我如何将双整数参数(用于索引)传递给那里?我是否应该编写另一种拆分 Array 的方法,然后在 QuickSort 方法中检查是否有其他列; "if(hThreadArray[0])then sort first array"?
  • @xBaskerville - 创建一个包含 8 个结构的数组,每个结构都有一对指针 (start, end) 或每个都有一个指向数组的指针和一对索引 (start, end) 或 (start , 最后的)。然后每个 CreateThread 调用的 lpParameter 将指向 8 个结构之一。
  • 所以,我创建了一个包含 8 个结构的数组,其中包含 2 个整数指针。每个进程是否应该自动获取其中 1 个?因为当我在 createthread 块中写入指针 [i] 时,它说“没有合适的转换函数“arrayPointers”到“LPVOID”存在”。很抱歉新手问题,但我无法得到它。
  • @xBaskerville - 使用 &amp;pointers[i]pointers+i 作为 lpParameter。
猜你喜欢
  • 2011-09-03
  • 2022-11-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多