首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在pthread_create()函数中传递矩阵作为参数?

如何在pthread_create()函数中传递矩阵作为参数?
EN

Stack Overflow用户
提问于 2021-09-27 23:05:14
回答 1查看 158关注 0票数 1

我刚刚开始进行O.S编程,并在探索线程。我想乘2个矩阵,并使用pthread_create()、pthread_join()和pthread_exit()函数得到它们的乘积。但是,pthread_create()将输入接受为void*而我想传递一个int**参数。

我已经试过了

  1. 在m3 ()函数中传递pthread_create()函数中的结果矩阵,方法是将其类型设置为(void*),然后将其类型转换回我的threadMultiply函数中的(int**),但这不起作用
  2. 将m1、m2、m3作为全局变量,但这也给我带来了错误。

我很困惑,再也不知道该怎么处理了。任何帮助都将不胜感激,谢谢

代码语言:javascript
复制
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

int** alloc(int, int);
void display(int**, int, int);
void* threadMultiply(void* para);

int main()
{
    int r1,c1,r2,c2,r3,c3;  // rows and columns of each matrix
    int **m1, **m2, **m3;   // all 3 matrices

    // took inputs for r1,c1,r2,c2
    m1=alloc(r1,c1);
    printf("Enter the %d elements of the first matrix\n", r1*c1);
    for(int i=0;i<r1;i++)
        for(int j=0;j<c1;j++)
            scanf("%d", &m1[i][j]);
    m2=alloc(r2,c2);
    printf("Enter the %d elements of the second matrix\n", r2*c2);
    for(int i=0;i<r2;i++)
        for(int j=0;j<c2;j++)
                scanf("%d", &m2[i][j]);
    display(m1, r1, c1);
    display(m2, r2, c2);
        
    if(c1 != r2)
    {
        printf("\nMatrices cannot be multiplied, check dimensions");
        return 0;
    }
        
    r3 = r1;
    c3 = c2;
    m3=alloc(r3,c3);
    int MAX_THREADS = r3*c3;
    pthread_t threads[MAX_THREADS];
 
    // Creating threads. 
    for (int i = 0; i < MAX_THREADS; i++) 
    {
        int *p;
        pthread_create(&threads[i], NULL, threadMultiply, (void*)(p));  //variable 'i' is of type int however function takes parameter of type void* so we have to do type-casting
    }
     
    // joining and waiting for all threads to complete
    for (int i = 0; i < MAX_THREADS; i++)
        pthread_join(threads[i], NULL);   
        
        printf("\nThe resultant matrix is:");
        display(m3, r3, c3);
        
return 0;
}

int** alloc(int row, int col)
{
    //dynamic memory allocation for first 2 matrices
    int **m=0;
    m=(int**)malloc(row*sizeof(int*));

    for(int i=0;i<row;i++)
    {
        *(m+i)=(int*)malloc(col*sizeof(int));
    }
    
return m;
}

void *threadMultiply(void *para)
{
    int i,j,k;
    for(i=0;i<r1;i++)
    {
        for(j=0;j<c2;j++)
        {
            m3[i][j] == 0
                for(k=0;k<c1;k++)                  
                    m3[i][j]+=m1[i][k] * m2[k][j];
        }
    }
    printf("thread finished ...");
    pthread_exit(NULL);
}

编辑:

所以在看完评论后,我又试了一次。代码编译,但给了我一个分段错误,不显示第二个矩阵

代码语言:javascript
复制
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

typedef struct matrix {  // using struct to reference 2 matrices in the threadMultiply function
    int r1, c1, r2, c2;
    int **m1;
    int **m2;
}mat;

int** alloc(int, int);
void display(int**, int, int);
void accept(int**, int, int);
void* threadMultiply(void* para);

int main()
{
    int r1,c1,r2,c2,r3,c3;  // rows and columns of each matrix
    int **a, **b, **c;  // all 3 matrices
    long int *ret_value;    //using long int, since int cannot be type casted to void
    mat *m;
    printf("Enter the number of rows and columns(m x n) of the first matrix\n");
        printf("Rows=");
        scanf("%d", &r1);
        printf("Columns=");
        scanf("%d", &c1);
        a=alloc(r1,c1);
        printf("Enter the %d elements of the first matrix\n", r1*c1);
    accept(a,r1,c1);
        printf("Enter the number of rows and columns(m x n) of the second matrix\n");
        printf("Rows=");
        scanf("%d", &r2);
        printf("Columns=");
        scanf("%d", &c2);
        b=alloc(r2,c2);
        printf("Enter the %d elements of the second matrix\n", r2*c2);
    accept(b,r2,c2);
    printf("\nThe first matrix is:");
    display(a, r1, c1);
        printf("\nThe second matrix is:");
        display(b, r2, c2);
    
        if(c1 != r2)
        {
            printf("\nMatrices cannot be multiplied, check dimensions");
            return 0;
        }
        
        r3 = r1;
        c3 = c2;
        c=alloc(r3,c3);
        m->m1 = a;
    m->m2 = b;
    m->r1 = r1;
    m->c1 = c1;
    m->r2 = r2;
    m->c2 = c2;
    
    // Creating one thread for each operation
    int MAX_THREADS = r3*c3;    
    pthread_t threads[MAX_THREADS];
    for (int i = 0; i < MAX_THREADS; i++) 
    {
        pthread_create(&threads[i], NULL, threadMultiply, (void*)(&m));  
    }
     
    // joining and waiting for all threads to complete
    for(int i=0;i<MAX_THREADS;i++) 
    {
        for(int j=0;j<r3;j++) 
        {
            for(int k=0;k<c3;k++)
            {
                //joining all the threads and retreiving value in ret_value
                if(pthread_join(threads[i],(void **) &ret_value) != 0)
                    perror("\nThread join failed.\n");
                c[j][k] += (long int)ret_value;   // int doesn't work here for some reason
            }
        }
    }
        
        printf("\nThe resultant matrix is:");
        display(c, r3, c3);
        
return 0;
}

int** alloc(int row, int col)
{
    //dynamic memory allocation for first 2 matrices
    int **m=0;
    m=(int**)malloc(row*sizeof(int));

    for(int i=0;i<row;i++)
        *(m+i)=(int*)malloc(col*sizeof(int)); //m+i so that we can access all the rows by incrementing value of i. (m+i) = m[i]
    
return m;
}

void display(int **m, int r, int c)
{
    int i,j;
    for(i=0;i<r;i++)
    {
        printf("\n[");
        for(j=0;j<c;j++)
        {
            if(j<c-1)
            {
                printf("%d\t", m[i][j]);
            }
            else 
            {
                printf("%d]", m[i][j]);
            }

        }
    }
}

void accept(int **a, int row, int col)
{
    int i, j;
    printf("Enter the elements\n");

    for(i = 0; i < row; i++)
        for(j = 0; j < col; j++)
            scanf("%d", (*(a + i) + j));  //same as a[i][j]
}
void *threadMultiply(void *para)
{
    mat *m = (mat*)para;
    int i = m->r1;
    int j = m->r2;
    int k = m->c2;
    long int return_val = m->m1[i][k] * m->m2[k][j];
    printf("\nThread finished ...");
    pthread_exit((void *) return_val);
}
EN

回答 1

Stack Overflow用户

发布于 2021-09-28 01:45:01

Recommendation指针声明(cppreference.com)

在那部分,

解释

指针用于间接,这是一种普遍存在的编程技术;它们可以用于实现按引用传递语义、访问具有动态存储时间的对象、实现“可选”类型(使用空指针值)、结构之间的聚合关系、回调(使用指向函数的指针)、泛型接口(使用指向无效的指针)等等。

指向无效的指针

指向任何类型的对象的指针都可以隐式转换为指针为void (可选的const或易失性限定的),反之亦然: ..。 指向void的指针用于传递未知类型的对象,这在一般接口中很常见: malloc返回void*,qsort需要用户提供的回调,该回调接受两个const *参数。pthread_create需要一个用户提供的回调,它接受并返回void*。在所有情况下,调用方都有责任在使用之前将指针转换为正确的类型。

这如何适用于您的代码

在你的主要职能:

代码语言:javascript
复制
// Creating threads. 
for (int i = 0; i < MAX_THREADS; i++) {
    int *p; // <- WARNING: pointer to int is uninitialized
    pthread_create(
        &threads[i], 
        NULL, 
        threadMultiply, 
        (void*)(p) // <- here you don't have to cast to void*
    );
}

指针p未初始化。将您希望作为参数(参数)传递给线程启动函数的任何对象的地址分配给p

因为你只能传递一个参数,所以如果你的乘法函数需要三个矩阵(以及它们的行和数),就会出现一个问题。因此,您可以将信息打包到结构中。

示例

代码语言:javascript
复制
//global
struct arg {
    int r1, c1, r2, c2, r3, c3;
    int **m1;
    int **m2;
    int **m3;
};

int main()
{
    //...

    struct arg p = {
        r1, c1, 
        r2, c2, 
        r3, c3, 
        m1, m2, m3
    }; //for demonstration purposes only, 
       //normally you would have to allocate a struct for each thread

    pthread_create(&threads[i], NULL, threadMultiply, &p); //need address of operator

    //...

}

为了避免引入新的结构,您当然可以将所有变量声明为全局变量,但是使用该结构,您可以将不同的参数传递给不同的线程(同时)。

然后是乘法函数:

代码语言:javascript
复制
void *threadMultiply(void *para)
{
    struct arg *p = para; //implicit cast
    int r1 = p->r1;
    int c1 = p->c1;
    //...
    int **m1 = p->m1;
    //...
    //do your multiplication
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69354084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档