使用 pthread 打印二维数组
Using pthread to print 2-d array
所以我有一个作业,说我创建了一个 2-D 数组[5][12],随机值在 1-99 之间。然后使用 pthreads,我必须对数组中的每个元素加 1 或减去 1,然后打印结果并将进程分成 2、3 或 4 个线程。线程数取决于用户在命令行上输入的内容。我有编译和运行的代码。但是,我想要的输出仅在输入数字 3 时打印。你们能告诉我我的代码哪里出错了吗?一开始我很难理解线程。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <pthread.h>
#include <iostream>
using namespace std;
int list[5][12];
int rows = 5;
int cols = 12;
int threadc;
void *threadf(void *arg)
{
int x = (int) arg;
for(int i = (x*60)/threadc; i < ((x+1) * 60)/threadc; i++)
{
for(int j = 0; j < 12; j++)
{
if (list[i][j] % 2 == 0)
list[i][j] += 1;
else
list[i][j] -= 1;
}
}
}
void cArray()
{
srand(time(NULL));
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 12; j++)
{
list[i][j] = rand() % 99 + 1;
}
}
}
void pArray(int list[][12], int rows, int cols)
{
cout << "n";
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
cout << list[i][j] << " ";
}
cout << "n";
}
}
int main(int argc, char *argv[])
{
if(argc != 2) exit(0);
threadc = atoi(argv[1]);
assert(threadc >= 2 && threadc <=4);
pthread_t *thread;
thread = new pthread_t [threadc];
if(thread == NULL)
exit(0);
cArray();
cout << "2-d Array: ";
pArray(list, rows, cols);
int t;
for(int i = 0; i < threadc; i++)
{
t = pthread_create(&thread[i], NULL, threadf, (void *)i);
if (t != 0)
return 1;
}
for(int i = 0; i < threadc; i++)
{
t = pthread_join(thread[i], NULL);
if(t != 0)
return 1;
}
cout << "Modified 2-d Array: ";
pArray(list, rows, cols);
return 0;
}
让我们看一下 x = 0 和线程 = 4 的外部 for 循环threadf
for(int i = (0*60)/4; i < ((0+1) * 60)/4; i++)
for(int i = 0; i < (1 * 60)/4; i++)
for(int i = 0; i < 60/4; i++)
for(int i = 0; i < 15; i++)
i
范围从 0 到 14。 我是这样使用的:list[i][j]
,所以请考虑写入list[14][11]
的位置。远远超出int list[5][12];
定义的界限 坏蓝精灵将会发生。未定义的行为,因此从技术上讲,没有人知道会发生什么。不过,我们可以做出一些很好的猜测。
int list[5][12];
int rows = 5; // probably overwritten by write to list[6][0]
int cols = 12; // probably overwritten by write to list[6][1]
int threadc; // probably overwritten by write to list[6][3]
所以row
和column
都在移动,但没有人在乎。代码从不使用它们。但是threadc
...到处都在用。实际上,它用于循环退出条件。这里可能会发生更多的坏事。它还确定要创建和连接的线程数。某些线程可能无法创建。程序可能会尝试加入比现有线程更多的线程。
无论如何,未定义的行为。我想我们都应该庆幸编译器没有生成命令战术核打击的代码。由于这是一个家庭作业问题,我不打算解开 OP 所需的数学运算,以使他们的for
循环正确地在多个线程上分配工作,但会建议他们考虑将数组视为大小为 5*12 的 1D 数组,并在单个for
循环中对自己进行 1D->2D 索引。
其他注意事项:
在main
中使用uintptr_t
而不是int
进行i
,在threadf
中使用x
。uintptr_t
保证转换为void *
对循环计数器和数组索引器使用无符号变量(如size_t
)。它们与uintptr_t
配合得很好,您几乎从不想要负数组索引。
对线程列表使用std::vector
而不是指针和new
。如果必须使用new
和指针,请记住在完成列表后将其删除。
看看是否可以使用std::thread
代替pthread
s。
将return
添加到threadf
。
不知何故,当创建的线程数为 2 时,thread_join
返回一个错误代码(在我的情况下22
)。如果在第二个循环中删除 return 语句,程序将打印最终输出。
for(int i = 0; i < threadc; i++)
{
t = pthread_join(thread[i], NULL);
if (t != 0)
return 1; // <- your program works if you comment out this.
}
根据此链接: http://minirighi.sourceforge.net/html/errno_8h.html 22 是 EINVAL,意思是"线程不可连接"。
由于您关心pthread_join的返回值,我建议您在thredf
末尾添加一个成功的终止函数(pthread_exit(NULL);
)。此外,为了避免@user4581301提到的缓冲区溢出,您可以传递指向数据的指针。
所以thredf
会像
void *threadf(void *arg)
{
cout << endl;
int x = *((int*)arg); // <- NOTICE HERE!
for(int i = (x*60)/threadc; i < ((x+1) * 60)/threadc; i++)
//...
}
pthread_exit(NULL); // <- NOTICE HERE!
}
而主要的:
int main(int argc, char *argv[])
{
if(argc != 2) exit(0);
threadc = atoi(argv[1]);
assert(threadc >= 2 && threadc <=4);
pthread_t *thread;
thread = new pthread_t [threadc];
int *data = new int[threadc]; // <- NOTICE HERE!
if(thread == NULL)
exit(0);
cArray();
cout << "2-d Array: ";
pArray(list, rows, cols);
int t;
for(int i = 0; i < threadc; i++)
{
data[i] = i;
// NOTICE HERE!
t = pthread_create(&thread[i], NULL, threadf, (void *)(&data[i]));
if (t != 0)
return 1;
}
// ...
- 将值从二维数组输出到文本文件
- 在二维数组中查找最小值和最大值?
- 移动二维数组中的字符
- 如何正确填充在堆上分配的二维数组?
- 传递二维数组时出现问题
- 具有随机数的二维数组不会更改
- 如何在C++中获取二维数组中最少的一列数?
- 如何使用用户输入变量制作二维数组?
- C++ 中动态二维数组的访问冲突
- 遍历二维数组的所有子数组
- 如何将文本文件读取到二维数组中并以 c++ 打印
- 重载运算符后打印二维数组<<
- 按列打印二维数组时出现问题
- 使用 pthread 打印二维数组
- 打印空白,而不是二维数组c++中的整数
- 根据用户输入对二维数组进行排序和打印
- 如何在C++中打印二维数组
- 无法将二维数组中的数据打印到C++的输出文件
- 如何在类函数中打印二维数组
- 如何打印二维数组作为一个矢量