我刚刚开始进行O.S编程,并在探索线程。我想乘2个矩阵,并使用pthread_create()、pthread_join()和pthread_exit()函数得到它们的乘积。但是,pthread_create()将输入接受为void*而我想传递一个int**参数。
我已经试过了
我很困惑,再也不知道该怎么处理了。任何帮助都将不胜感激,谢谢
#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);
}编辑:
所以在看完评论后,我又试了一次。代码编译,但给了我一个分段错误,不显示第二个矩阵
#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);
}发布于 2021-09-28 01:45:01
Recommendation:指针声明(cppreference.com)
在那部分,
解释
指针用于间接,这是一种普遍存在的编程技术;它们可以用于实现按引用传递语义、访问具有动态存储时间的对象、实现“可选”类型(使用空指针值)、结构之间的聚合关系、回调(使用指向函数的指针)、泛型接口(使用指向无效的指针)等等。
指向无效的指针
指向任何类型的对象的指针都可以隐式转换为指针为void (可选的const或易失性限定的),反之亦然: ..。 指向void的指针用于传递未知类型的对象,这在一般接口中很常见: malloc返回void*,qsort需要用户提供的回调,该回调接受两个const *参数。pthread_create需要一个用户提供的回调,它接受并返回void*。在所有情况下,调用方都有责任在使用之前将指针转换为正确的类型。
这如何适用于您的代码
在你的主要职能:
// 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。
因为你只能传递一个参数,所以如果你的乘法函数需要三个矩阵(以及它们的行和数),就会出现一个问题。因此,您可以将信息打包到结构中。
示例
//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
//...
}为了避免引入新的结构,您当然可以将所有变量声明为全局变量,但是使用该结构,您可以将不同的参数传递给不同的线程(同时)。
然后是乘法函数:
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
}https://stackoverflow.com/questions/69354084
复制相似问题