- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个程序需要对大量的大数值分布进行排序。为了减少执行此操作所需的时间,我正在尝试对其进行多线程处理。
我写了一个小而简单的程序抽象来尝试隔离问题。我相信我遇到了堆栈溢出,或者达到了操作系统的堆栈限制,因为我的测试程序在以下情况下反射(reflect)了段错误问题:
喵喵
#include <boost/thread/thread.hpp>
#include <vector>
#include <stdlib.h> // for rand()
void swapvals(double *distribution, const size_t &d1, const size_t &d2)
{
double temp = 0;
temp = distribution[d2];
distribution[d2] = distribution[d1];
distribution[d1] = temp;
//std::swap(distribution[d1], distribution[d2]);
}
size_t partition(double *distribution, size_t left, size_t right)
{
const double pivot = distribution[right];
while (left < right) {
while ((left < right) && distribution[left] <= pivot)
left++;
while ((left < right) && distribution[right] > pivot)
right--;
if (left < right)
{
swapvals(distribution, left, right);
}
}
return right;
}
void quickSort(double *distribution, const size_t left, const size_t right)
{
if (left >= right) {
return;
}
size_t part = partition(distribution, left, right);
quickSort(distribution, left, part - 1);
quickSort(distribution, part + 1, right);
}
void processDistribution(double *distributions, const size_t distribution_size)
{
std::clog << "beginning qsorting." << std::endl;
quickSort(distributions, 0, distribution_size - 1);
std::clog << "done qsorting." << std::endl;
}
int main(int argc, char* argv[])
{
size_t distribution_size = 65000;
size_t num_distributions = 10;
std::vector<double *> distributions;
// Create num_distributions distributions.
for (int i = 0; i < num_distributions; i++)
{
double * new_dist = new double[distribution_size];
for (int k = 0; k < distribution_size; k++)
{
// Works when I have actual numbers in the distributions.
// Seg faults when all the numbers are the same.
new_dist[k] =1;
//new_dist[k] = rand() % 1000 + 1; // uncomment this, and it works.
}
distributions.push_back(new_dist);
}
// Submit each distribution to a quicksort thread.
boost::thread_group threads;
for (std::vector<double *>::const_iterator it=distributions.begin(); it != distributions.end(); ++it)
{
// It works when I run processDistribution directly. Segfaults when I run it via threads.
//processDistribution(*it, distribution_size);
threads.create_thread(boost::bind(&processDistribution, *it, distribution_size));
}
threads.join_all();
// Show the results of the sort for all the distributions.
for (std::vector<double *>::const_iterator it=distributions.begin(); it != distributions.end(); ++it)
{
for (size_t i = 0; i < distribution_size; i++)
{
// print first and last 20 results.
if (i < 20 || i > (distribution_size - 20))
std::cout << (*it)[i] << ",";
}
std::cout << std::endl;
}
}
核心文件产量的 GDB 分析:
Error in re-setting breakpoint -1: aix-thread: ptrace (52, 18220265) returned -1 (errno = 3 The process does not exist.)
Error in re-setting breakpoint -1: aix-thread: ptrace (52, 18220265) returned -1 (errno = 3 The process does not exist.)
Error in re-setting breakpoint -2: aix-thread: ptrace (52, 18220265) returned -1 (errno = 3 The process does not exist.)
Error in re-setting breakpoint -3: aix-thread: ptrace (52, 18220265) returned -1 (errno = 3 The process does not exist.)
Core was generated by `testthreads'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00000001000056bc in partition (distribution=0x1101d1430, left=0, right=63626) at testthreads.cpp:18
warning: Source file is more recent than executable.
18
(gdb) bt 7
#0 0x00000001000056bc in partition (distribution=0x1101d1430, left=0, right=63626) at testthreads.cpp:18
#1 0x0000000100005834 in quickSort (distribution=0x1101d1430, left=0, right=63626) at testthreads.cpp:42
#2 0x0000000100005850 in quickSort (distribution=0x1101d1430, left=0, right=63627) at testthreads.cpp:43
#3 0x0000000100005850 in quickSort (distribution=0x1101d1430, left=0, right=63628) at testthreads.cpp:43
#4 0x0000000100005850 in quickSort (distribution=0x1101d1430, left=0, right=63629) at testthreads.cpp:43
#5 0x0000000100005850 in quickSort (distribution=0x1101d1430, left=0, right=63630) at testthreads.cpp:43
#6 0x0000000100005850 in quickSort (distribution=0x1101d1430, left=0, right=63631) at testthreads.cpp:43
(More stack frames follow...)
(gdb) frame 0
#0 0x00000001000056bc in partition (distribution=0x1101d1430, left=0, right=63626) at testthreads.cpp:18
18
(gdb) info locals
pivot = 1
(gdb) info args
distribution = 0x1101d1430
left = 0
right = 63626
(gdb)
此外,我的实际程序处理更多的线程和分布。那里的 GDB 检查经常显示更奇怪的堆栈跟踪,看起来像内存损坏(注意 swapVals 是如何用 d1 = 12119 调用的,但在分区堆栈框架内它作为 4568618016 通过):
(gdb) bt 3
#0 0x00000001002aa0b8 in ScenRankReplacer<double>::swapvals (this=0xfffffffffffdfc8, distribution=..., d1=@0x1104c8178: 4568618016, d2=@0x1104c8140: 4568416720, ranking_values=0x1104c81d0,
r1=@0x1104c8170: 1152921504606838728, r2=@0x1002a16c8: 6917529029728344952) at ScenRankReplacer.h:96
#1 0x00000001002a7120 in ScenRankReplacer<double>::partition (this=0xfffffffffffdfc8, distribution=..., ranking_values=0x11069ae50, left=1, right=24237) at ScenRankReplacer.h:122
#2 0x00000001002a16c8 in ScenRankReplacer<double>::quickSort (this=0xfffffffffffdfc8, distribution=..., ranking_values=0x11069ae50, left=1, right=24237) at ScenRankReplacer.h:91
(More stack frames follow...)
(gdb) frame 1
#1 0x00000001002a7120 in ScenRankReplacer<double>::partition (this=0xfffffffffffdfc8, distribution=..., ranking_values=0x11069ae50, left=1, right=24237) at ScenRankReplacer.h:122
122 swapvals(distribution, mid, left, ranking_values, mid - 1, left - 1);
(gdb) p mid
$1 = 12119
(gdb) p left
$2 = 1
所以...我的问题:
错误发生在编译级别O2。线程模型:aixgcc 版本 4.8.3 (GCC)
最佳答案
这看起来可能与堆栈空间有关。线程很重要,因为虽然所有线程都有自己的堆栈,但这些堆栈都共享同一个内存池。堆栈通常会根据需要增长,直到它们遇到已使用的内存,在这种情况下,这可能是来自另一个线程的堆栈。单线程程序不会有这个问题,并且可以增加它的堆栈。 (对于多个线程,您同时进行多种排序,这将需要更多堆栈空间。)
解决此问题的一种方法是删除递归并使用一些循环和本地存储来替换它。像这样的(未编译或测试过的)代码:
void quickSort(double *distribution, size_t left, size_t right) {
std::vector<std::pair<size_t, size_t>> ranges;
for (;;) {
for (;;) {
if (left <= right)
break;
size_t part = partition(distribution, left, right);
// save range for later to replace the second recursive call
ranges.push_back(std::make_pair(part + 1, right));
// set right == part - 1, then loop, to replace the first recursive call
right = part - 1;
}
if (ranges.empty())
break;
// Take top off of ranges for the next loop, replacing the second recursive call
left = ranges.back().first;
right = ranges.back().second;
ranges.pop_back();
}
}
关于C++/调试(AIX 上的 g++)递归快速排序导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32575470/
如何更改循环中变量的名称?比如 number1 、 number2 、 number3 、 number4 ? var array = [2,4,6,8] func ap ( number1: Int
我想设置 View 的背景颜色并在一定延迟后将其更改为另一种颜色。这是我的尝试方式: print("setting color 1") self.view.backgroundColor = UICo
我在使用 express-session 时遇到问题。 session 数据不会在请求之间持续存在。 正如您在下面的代码中看到的那样,/join 路由设置了一些 session 属性,但是当 /sur
我试图从叶渲染器获得一个非常简单的结果,用于快速 Steam 的 for 循环。 我正在上传叶文件 HTML,因为它不接受此处格式正确的代码 - 下面的pizza.swift代码- import
你们中有人有什么好的链接可以与我分享吗?我正在寻找一个 FAST 程序员编辑器,它可以非常快速地打开包含超过 100, 000 行代码的文件?我目前正在使用记事本自动取款机,打开一个 29000 行长
我现在正在处理眼动追踪数据,因此拥有一个巨大的数据集(想想数百万行),因此希望有一种快速的方法来完成此任务。这是它的简化版本。 数据告诉您眼睛在每个时间点正在查看的位置以及我们正在查看的每个文件。 X
我是新手,想为计时器或其他设备选择提示音。 如何打开此列表,以选择其中一种声音? Alert sound list 最佳答案 您将无法在应用中使用系统声音。 但是,您可以包括自己的声音文件,并将其显示
我编写了以下代码来构建具有顺序字符串的数组。 它的工作方式与我预期的一样,但我希望它能更快地运行。有没有更有效的方法在PowerShell中产生我想要的结果? 我是PowerShell的新手,非常感谢
我有一个包含一些非唯一行的矩阵,例如: x 尝试 y <- rle(apply(x, 1, paste, collapse = " ")) # y$lengths is the vector con
我的函数“keyboardWillShown”有问题。所以我想要的是菜单打开时,菜单正好出现在键盘上方。它可以在Iphone 8 plus,8、7、6上完美运行。但是,当我在模拟器上运行Iphone
我正在尝试通过Swift 5中的HTTP get方法从API提取数据。它在启动时成功加载了数据,但是当我刷新页面时,它说“索引超出范围”,这是因为数据是不再会在我的日志中读取,因此索引中没有任何内容。
我想做什么: 从我的数据库中获取时间戳并将其转换为用户的时区。 我的代码: let tryItNow = "\(model.timestampName)" let format = D
给定字体名称和字体大小,如何查找字符串的宽度(CGFloat)? (目标是将UIView的宽度设置为足以容纳字符串的宽度。) 我有两个字符串:一个重复“1”,重复36次,另一个重复“M”,重复36次。
我正在尝试解析此JSON ["Items": ( { AccountBalance = 0; AlphabetType = 3; Description = "\U0631\U
我在UINavigationBar内放置了一个UILabel。 我想根据navigationBar的高度增加该标签的字体大小。当navigationBar很大时,我希望字体大小更大;当滚动并缩小nav
我想将用户输入限制为仅有效数字并使用以下内容: func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, rep
目前我有一个包含超过 100.000 张图像的数据库,它们大小不一或类似,但我想为我的公司制作以下内容: 我插入/上传一张图片,系统返回最有可能相同的图片。我不知道使用什么算法,但它需要快速。我可以预
在我的 swift 项目中,我有一个按钮,我想在标签上打印按下该按钮的时间。 如何解决这个问题? 最佳答案 添加到DHEERAJ的答案中,您只需在func press(sender: UIButton
我必须发表评论,尝试在解析中导入数组。然而,有一个问题。 当我尝试从 Parse 加载数组时,我的输出是 ("Blah","Blah","Blah")这是一个元组...而不是一个数组 TT... 如何
我的应用程序有一个名为 MyDevice 的类,我用它来与硬件通信。该硬件是可选的,实例变量也是可选的: var theDevice:MyDevice = nil 然后,在应用程序中,我必须初始化设备
我是一名优秀的程序员,十分优秀!