C语言 在需要整数的地方使用了聚合值

mccptt67  于 2023-03-01  发布在  其他
关注(0)|答案(1)|浏览(173)
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdint.h>

#define ARRAY_SIZE 50000000

// The following is a struct in C.
// This paradigm allows for arbitrary data to be stored
// in a structured way. This also allows for multiple
// parameters to be passed to a thread function.
// You should use this struct with the add_arrays
// function when running using threads.
struct data {
  int* a;
  int* b;
  int* c;
  int start_idx; // Where the thread should start in an array
};

void* add_arrays(void* arg) {
    
    // Elements from the thread_data struct can be accessed here
    // Ex thread_data.a

    // @TODO
    // Split the work of c[i] = a[i] + b[i] between two threads.
    // HINT: Work should be split half-and-half. Use start_idx
    // to coordinate this.
    // +5
    struct data thread_data = *(struct data*) arg;
    int* a = thread_data.a;
    int* b = thread_data.b;
    int* c = thread_data.c;
    int start_idx = thread_data.start_idx;
    int end_idx = start_idx + ARRAY_SIZE/2;
    for (int i = start_idx; i < end_idx; i++) {
        c[i] = a[i] + b[i];
    }
    pthread_exit(NULL);
}

void* rand_init(void* arg) {
    int range_start = 0;
    int range_end = 9;

    // @TODO
    // Fill an array with random variables using a thread.
    // Remember to use rand_r and not rand. You will also need to
    // change how the random seed is calculated such that it is unique
    // for each thread. For more details, see the assignment PDF or README.
    // HINT: The input parameter should be an array, not a struct.
    // +5
    int* a = (int*) arg;
    unsigned int seed = time(NULL) ^ (unsigned int) (uintmax_t) pthread_self();
    for (int i = 0; i < ARRAY_SIZE/2; i++) {
        a[i] = rand_r(&seed) % 10;
    }
    pthread_exit(NULL);
}

int main(void) {
    // @TODO
    // Allocate the source arrays (a, b, c)
    // a and b are the source arrays.
    // c is the result storage array.
    // c[i] should equal a[i] + b[i]
    // Make sure to error check.
    // +1
    int *a, *b, *c;

    //allocating space for arrays and error checking
    a = (int*)(malloc(ARRAY_SIZE*sizeof(int)));
    if (a == NULL){
        printf("Not enough memory");
        exit(1);
    }

    b = (int*)(malloc(ARRAY_SIZE*sizeof(int)));
    if (b == NULL){
        printf("Not enough memory");
        free(a);
        exit (1);
    }
    c = (int*)(malloc(ARRAY_SIZE*sizeof(int)));
    if (c == NULL){
        printf("Not enough memory");
        free(a);
        free(b);
        exit(1);
    }

    // @TODO
    // Create two pthreads and initialize a and b with
    // random numbers using both threads. The full operation
    // should be timed and the period printed.
    // +4
    clock_t start_time, end_time;
    double execution_time;

    pthread_t thread1, thread2;


    start_time = clock();
    pthread_create(&thread1, NULL, rand_init, a);
    pthread_create(&thread2, NULL, rand_init, b);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    end_time = clock();

    execution_time = ((double)(end_time - start_time))/CLOCKS_PER_SEC;
    execution_time = execution_time*1000;
    printf("Total init time: %.2f ms\n", execution_time);

    // @TODO
    // Define and prepare two structs for each thread.
    // The structs should contain data relevent to the add operation.
    // +2
    struct data data1 = {a, b, c, 0};
    struct data data2 = {a, b, c, ARRAY_SIZE/2};

    // @TODO
    // Reuse your pthreads from earlier and time your add_arrays function
    // as it runs on both threads.
    // +2

    start_time = clock();
    pthread_create(&thread1, NULL, add_arrays, &data1);
    pthread_create(&thread2, NULL, add_arrays, &data2);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    end_time = clock();
    execution_time = ((double)(end_time - start_time))/CLOCKS_PER_SEC;
    execution_time = execution_time*1000;

    // @TODO
    // Print out the first 10 elements of the result array and the final
    // period for the add_arrays threaded function runs.
    // +2
    for (int i = 0; i < 10; i++){ //first 10 elements
        printf("%d ", c[i]);
    }
    printf("\nTotal add time: %.2f ms\n", execution_time); //add function time taken

    // Free the memory
    // +1

    free (a);
    free (b);
    free (c);

    return 0;
}
Q2.c: In function 'rand_init':
Q2.c:58:5: error: aggregate value used where an integer was expected
     unsigned int seed = time(NULL) ^ (unsigned int) (uintmax_t) pthread_self();
     ^~~~~~~~
Q2.c:60:16: warning: implicit declaration of function 'rand_r' [-Wimplicit-function-declaration]
         a[i] = rand_r(&seed) % 10;

我在使用docker来运行linux pthreads时遇到了以下错误。所有这些对我来说都很复杂。我不确定我们如何使用线程来生成随机数。
我从chatGPT unsigned int seed = time(NULL) ^ (unsigned int) (uintmax_t) pthread_self();获得了这一行
但无论我遵循什么解决方案的代码不会运行。我想知道这是由于我的代码或我的开发环境中的错误。任何帮助将不胜感激。

db2dz4w8

db2dz4w81#

多个问题:

  • 缺少#include <stdio.h>
  • unsigned int seed = time(NULL) ^ (unsigned int) (uintmax_t) pthread_self();行中,将pthread_self()的返回值转换为整数:这可能是导致警告的原因。请尝试使用以下内容:
unsigned int seed = time(NULL) ^ (unsigned int)(uintptr_t)arg;

或者,您可以使seed成为线程data的一部分,并使用srand(time(NULL))rand()main()中初始化它。

  • 在多线程程序中使用clock()来测量运行时间可能没有意义。使用gettimeofday()似乎更可靠。
  • rand_r()出现错误:这是非常令人惊讶的,因为这个函数是POSIX的一部分,在<stdlib.h>中声明。你可以尝试使用rand()来检查程序是否编译。然而使用rand_r()似乎更合适,所以修复问题应该得到修复。
  • 使用range_startrange_end的表达式应为:
a[i] = range_start + rand_r(&seed) % (range_end + 1 - range_start);

然而,注意,该表达式可能引入对于该测试程序不显著的小偏差。

相关问题