【问题标题】:C - writing a multi-threaded program to square numbersC - 将多线程程序编写为平方数
【发布时间】:2016-02-28 01:54:26
【问题描述】:

我正在尝试编写一个程序,该程序使用多个线程来计算 1-10000 之间的数字的平方。我试图让每个线程一次平方一个数字,最多 8 个线程。这意味着线程 1-8 将对 8 个数字进行平方,当它们完成时,它们开始对下一个数字进行平方,等等。

我的代码编译没有错误,但没有将任何内容打印到输出文件。我无法准确指出问题所在,所以有人可以给我一些提示或指出正确的方向吗?

另外,对于那些提供代码来提供帮助的人,我已经评论了我不想被更改的部分。我怀疑他们无论如何都需要,但我将它们用于该项目的其他部分,并希望保持它们相同。 谢谢。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>

#define NUMBER_OF_THREADS 8
#define START_NUMBER 1
#define END_NUMBER 10000

FILE *f;

void *sqrtfunc(void *tid) { //function for computing squares
    int i;
    for (i = START_NUMBER; i<=END_NUMBER; i++){
        fprintf(f, "%lu squared = %lu\n", i, i*i);
    }
}

int main(){
    //Do not modify starting here
    struct timeval start_time, end_time;
    gettimeofday(&start_time, 0);
    long unsigned i;
    f = fopen("./squared_numbers.txt", "w");
    //Do not modify ending here

    pthread_t mythreads[NUMBER_OF_THREADS]; //thread variable
    long mystatus;

    for (i = 0; i < NUMBER_OF_THREADS; i++){ //loop to create 8 threads
        mystatus = pthread_create(&mythreads[i], NULL, sqrtfunc, (void *)i);
        if (mystatus != 0){ //check if pthread_create worked
            printf("pthread_create failed\n");
            exit(-1);
        }
    }
    for (i = 0; i < NUMBER_OF_THREADS; i++){
        if(pthread_join(mythreads[i], NULL)){
            printf("Thread failed\n");
        }
    }
    exit(1);

    //Do not modify starting here
    fclose(f);
    gettimeofday(&end_time, 0);
    float elapsed = (end_time.tv_sec-start_time.tv_sec) * 1000.0f + \
                    (end_time.tv_usec-start_time.tv_usec) / 1000.0f;
    printf("took %0.2f milliseconds\n", elapsed);
    //Do not modify ending here
}

我能想到的唯一解决方案是移动创建 8 个线程的 for 循环并将其放在 sqrtfunc 函数的 for 循环中。这行得通吗?提前致谢。

【问题讨论】:

  • 好吧,所有线程都在争夺同一个文件。
  • @user3528438 你能告诉我如何解决这个问题吗?当我pthread_create 时,他们不应该能够打印到它吗?
  • 我建议添加一些错误处理,例如检查 fopen 是否成功。我已经测试了您的代码,并在文件中打印了以下输出。 1 平方 = 1 2 平方 = 4 3 平方 = 9 ......9998 平方 = 99960004 9999 平方 = 99980001 10000 平方 = 100000000 4 平方 = 16 ... 9 平方 = 81 10 平方 = 100
  • 即使他们能够打印出来也会像这样
  • 编译时,始终启用所有警告,然后修复这些警告。 (对于gcc,至少使用:-Wall -Wextra -pedantic 我也使用:-Wconversion -std=gnu99

标签: c multithreading pthreads


【解决方案1】:

为了避免线程争夺文件访问的问题,每个线程都可以返回结果,该结果将由主进程放入文件。或者线程可以在仅写入该字符串之前准备结果字符串并锁定。以下是第一个解决方案

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>

#define NUMBER_OF_THREADS 8
#define START_NUMBER 1
#define END_NUMBER 1000

FILE* f;

struct Thread_argument
{
    unsigned long long start;
    int range;
};

void* sqrtfunc( void* a ) //function for computing squares
{
    struct Thread_argument* argument = ( struct Thread_argument* )a;
    unsigned long long* result = calloc( argument->range, sizeof( unsigned long long ) );

    for( int i = 0; i < argument->range; i++ )
    {
        result[i] = ( argument->start + i ) * ( argument->start + i );
    }

    free( a );
    return result;
}

int main()
{
    //Do not modify starting here
    struct timeval start_time, end_time;
    gettimeofday( &start_time, 0 );
    long unsigned i;
    f = fopen( "./squared_numbers.txt", "w" );
    //Do not modify ending here
    pthread_t mythreads[NUMBER_OF_THREADS]; //thread variable
    long mystatus;
    int END = END_NUMBER + 1;
    int const range = ( END - START_NUMBER ) / ( NUMBER_OF_THREADS - 1 );

    for( int i = 0; i < NUMBER_OF_THREADS; i++ ) //loop to create 8 threads
    {
        struct Thread_argument* ta = malloc( sizeof( struct Thread_argument ) );
        ta->start = i * range + START_NUMBER;
        ta->range = range;

        if( i == NUMBER_OF_THREADS - 1 )
        {
            ta->range = ( END - START_NUMBER ) % ( NUMBER_OF_THREADS - 1 );
        }

        mystatus = pthread_create( &mythreads[i], NULL, sqrtfunc, ( void* )ta );

        if( mystatus != 0 ) //check if pthread_create worked
        {
            printf( "pthread_create failed\n" );
            exit( -1 );
        }
    }

    unsigned long long* results[NUMBER_OF_THREADS]; //thread variable

    for( int i = 0; i < NUMBER_OF_THREADS; i++ )
    {
        if( pthread_join( mythreads[i], ( void** )&results[i] ) )
        {
            printf( "Thread failed\n" );
        }
    }

    for( int i = 0; i < NUMBER_OF_THREADS - 1; i++ )
    {
        for( int j = 0; j < range; ++j )
        {
            fprintf( f, "%d %lld\n", i * range + j + START_NUMBER, results[ i ][ j ] );
        }

        free( results[ i ] );
    }

    int leftovers = ( END - START_NUMBER ) % ( NUMBER_OF_THREADS - 1 );

    for( int i = 0; i < leftovers; ++i )
    {
        fprintf( f, "%d %lld\n", ( NUMBER_OF_THREADS - 1 ) * range + i + 1, results[ NUMBER_OF_THREADS - 1 ][ i ] );
    }

    free( results[ NUMBER_OF_THREADS - 1 ] );
    fclose( f );
    //Do not modify starting here
    gettimeofday( &end_time, 0 );
    float elapsed = ( end_time.tv_sec - start_time.tv_sec ) * 1000.0f + \
                    ( end_time.tv_usec - start_time.tv_usec ) / 1000.0f;
    printf( "took %0.2f milliseconds\n", elapsed );
    //Do not modify ending here
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多