Articles of pthreads

并发使用多个线程写入文件

我有一个用户级别的程序,它使用标志O_WRONLY|O_SYNC打开一个文件。 该程序创build256个线程,试图将每个数据的256个或更多的字节写入文件。 我希望总共有1280000个请求,总计大约有300MB的数据。 一旦1280000个请求完成,程序结束。 我使用pthread_spin_trylock()来增加一个跟踪已完成请求数量的variables。 为了确保每个线程都写入一个唯一的偏移量,我使用pwrite()并根据已经写入的请求数来计算偏移量。 因此,在写入文件时,我不使用任何互斥锁(这种方法确保数据完整性吗?) 当我检查pwrite()调用被阻塞的平均时间和使用blktracefind的相应数字(即平均Q2C时间 – 这是BIOs整个生命周期的时间的度量)时,我发现这是有显着的差异。 实际上,给定BIO的平均完成时间远远大于pwrite()调用的平均等待时间。 这种差异背后的原因是什么? 这些数字不应该相似,因为O_SYNC确保数据在返回之前实际写入物理介质?

如何find一个pthread是否有挂起的取消请求

我想find一个线程, pthread_cancel是否被调用。 我不想使用一些表格,并保持这一点。 有没有可用的库函数? 我不想取消线程使用一些取消点function取消线程,如果有任何挂起的取消请求,我只是想知道是否有任何挂起的取消请求。

在pthread程序中,例程的额外执行时间是多less?

我写了四个不同的程序来计算两个文件中的总字数。 这四个版本看起来大致相同。 前三个版本使用两个线程来计数,只是三个语句的顺序不同。 最后一个版本使用一个线程来计数。 我会先列出每个版本的不同部分和通用部分,然后列出每个版本的输出和我的问题。 不同的部分: // version 1 count_words(&file1); pthread_create(&new_thread, NULL, count_words, &file2); pthread_join(new_thread, NULL); // version 2 pthread_create(&new_thread, NULL, count_words, &file2); count_words(&file1); pthread_join(new_thread, NULL); // version 3 pthread_create(&new_thread, NULL, count_words, &file2); pthread_join(new_thread, NULL); count_words(&file1); // version 4 count_words(&file1); count_words(&file2); 通用部分:( 将不同的部分插入到这个通用部分来制作一个完整的版本 ) #include <stdio.h> #include <pthread.h> #include <ctype.h> #include <stdlib.h> #include <time.h> #define […]

我需要debuggingpthreads?

我想debugging我的自定义Linux发行版上的pthreads,但我错过了一些东西。 我的主机是Ubuntu 12.04,我的目标是使用crosstool-NG交叉编译器工具集构build的i486定制embedded式Linux,其余的操作系统是使用Buildroot制作的。 我将列举事实: 我可以在我的目标上运行multithreading应用程序 当我在目标上运行multithreading应用程序时, Google Breakpad无法创build崩溃报告。 当我在我的主机上运行完全相同的应用程序与完全相同的构buildBreakpad库将成功。 GDB无法在我的目标上debuggingmultithreading应用程序。 例如 $./gdb -n -ex "thread apply all backtrace" ./a.out –pid 716 dlopen failed on 'libthread_db.so.1' – /lib/libthread_db.so.1: undefined symbol: ps_lgetfpregs GDB will not be able to debug pthreads. GNU gdb 6.8 我不认为ps_lgetfpregs是因为这个问题。 我的crosstool构build了libthread_db.so文件,并将其放在目标上。 我的crosstool构build为我的目标创build了gdb,所以它应该与我在目标上运行的库相链接。 如果我在我的主机上运行gdb,对我的testing应用程序,我得到每个运行线程的回溯。 我怀疑Breakpad的问题与GDB的问题有关,但是我不能证实这一点。 唯一的共同点是缺乏multithreadingdebugging。 我的主机和目标之间有一些关键的区别阻止了我能够debugging目标上的pthreads。 有谁知道它是什么? 编辑: TI的Denys Dmytriyenko表示: 通常情况下,GDB不是很挑剔,你可以混合使用不同版本的gdb和gdbserver。 但是,不幸的是,如果您需要debuggingmultithreading应用程序,那么对于特定的API有一些依赖关系… 例如,如果您没有为线程支持正确构buildGDB,则可能会看到以下消息之一: […]

什么是pthread取消点用于?

关于几个问题,讨论了pthread取消点( http://man7.org/linux/man-pages/man3/pthread_cancel.3.html )。 在某些情况下,被调查者说除非程序员知道他们做得很好,否则不应使用取消点。 我的问题—什么是pthread取消点用于? [从评论更新] 取消点是否允许取消那些特定的API调用? 为什么这些而不是其他人? 任何人都想使用他们的东西吗? 他们是在内核中解决问题的黑客攻击手段吗?或者他们是在POSIX系统中固有的东西? 你想在用户级代码中使用取消点还是只在API中使用取消点?

一个空的堆竞技场的开销

我的工具是Linux,gcc和pthreads。 当我的程序从多个线程中调用新的/删除的时候,当这个堆存在争用的时候,就会创build'竞技场'(参见http://www.bozemanpass.com/info/linux/malloc/Linux_Heap_Contention.html )。 我的程序全天候运行,而且两周后仍然偶尔会创build竞技场。 我认为最终可能会有像线程一样多的领域。 ps(1)显示惊人的内存消耗,但我怀疑只有一小部分实际映射。 什么是一个空的舞台上的“开销”? (如果所有的分配被限制在传统堆中,每个竞技场使用的内存多less?) 有没有办法在n场之前强制创作? 有什么办法可以迫使空的场地遭到破坏吗?

在用户空间中实现可取消的系统调用

我正在努力在Linux上实现pthread的取消,而没有任何“不愉快的行为”(有些人可能会说错误)在我的其他一些最近的问题中讨论。 到目前为止,用于pthread取消的Linux / glibc方法一直是将其视为不需要内核支持的方法,并且可以在库级别处理纯粹通过在进行系统调用之前启用asynchronous取消,并恢复先前的取消状态系统调用返回之后。 这至less有两个问题,其中一个非常严重: 取消可以在系统调用从内核空间返回之后,但在用户空间保存返回值之前执行。 如果系统调用分配了资源,这将导致资源泄漏,并且无法使用取消处理程序对其进行修补。 如果在线程在可取消的系统调用中被阻塞时处理信号,则整个信号处理程序在启用asynchronous取消的情况下运行。 这可能是非常危险的,因为信号处理程序可能会调用asynchronous信号安全但不是asynchronous取消安全的函数。 我解决这个问题的第一个想法是设置一个标志,线程是在取消点,而不是启用asynchronous取消,当这个标志被设置,取消信号处理程序检查保存的指令指针,看看它是否指向系统调用指令(arch-specific)。 如果是这样,这表示系统调用没有完成,并将在信号处理程序返回时重新启动,因此我们可以取消。 如果没有,我假定系统调用已经返回,并推迟取消。 但是,还有一个竞争条件 – 可能线程还没有到达系统调用指令,在这种情况下,系统调用可能会阻止并且不会响应取消。 另一个小问题是,如果在input信号处理程序时设置了取消点标志,则从信号处理程序执行的不可取消的系统调用错误地变为可取消。 我正在寻找一种新的方法,并寻找反馈意见。 必须满足的条件: 系统调用完成之前收到的任何取消请求必须在系统调用块之前的任何显着的时间间隔内执行,而不是由于信号处理程序的中断而暂停重启。 系统调用完成后收到的任何取消请求必须推迟到下一个取消点。 我想到的想法需要为可取消的系统调用包装器进行专门的组装。 基本的想法是: 将即将到来的syscall指令的地址推入堆栈。 将堆栈指针存储在线程本地存储器中。 从线程本地存储testing取消标志; 如果设置,则跳转到取消例程。 进行系统调用。 清除保存在线程本地存储中的指针。 取消操作将涉及: 在目标线程的线程本地存储中设置取消标志。 testing目标线程的线程本地存储中的指针; 如果不为空,则向目标线程发送取消信号。 取消信号处理程序将然后: 检查保存的堆栈指针(在信号上下文中)是否等于线程本地存储器中保存的指针。 如果没有,那么取消点就被一个信号处理程序中断了,现在没有什么可做的了。 检查程序计数器寄存器(保存在信号上下文中)是否小于或等于保存在堆栈指针处的地址。 如果是这样,这意味着系统调用还没有完成,我们执行取消。 我现在看到的唯一问题是在信号处理程序的第1步中:如果它决定不采取行动,那么在信号处理程序返回后,线程可能会在系统调用上被阻塞,忽略挂起的取消请求。 为此,我看到两个可能的解决scheme: 在这种情况下,安装一个计时器来传递信号到特定的线程,基本上每一毫秒都会重试,直到我们运气好。 再次提高取消信号,但不取消取消信号,从取消信号处理器返回。 当中断的信号处理程序返回时它会自动取消屏蔽,然后我们可以再试一次。 不过,这可能会干扰信号处理程序中取消点的行为。 任何想法哪种方法最好,或者是否还有其他更重要的缺陷?

检查当前线程是否是主线程

我如何检查当前线程是否是Linux上的主线程? 它看起来像gettid()只返回一个PID,但似乎Linux不保证与main()的线程总是有一个常量和统一的PID。 原因是我有一个自动并行化进行,我想确保pthread_create()不在一个已经在pthread_create()创build的线程上运行的函数中调用。

如何使线程睡眠/阻塞纳秒(或至less几毫秒)?

我怎么能阻止我的线程(也许进程)纳秒或可能一毫秒(至less)期? 请注意,我不能使用睡眠,因为睡觉的参数总是在几秒钟内。

伪terminal的使用 – C

我使用特定的会话编号创build了一个pThread 。 如果pThread产生了,我试着让另一个进程运行使用openpty启动的伪terminal。 这是代码的一部分: if (openpty(&(numa_pst[session][0]),&(numa_pst[session][1]), NULL, NULL, NULL) != 0) { int err_code = errno; sprintf (line_temp, "*** ERROR: numa openpty failed with:\n%s\n", strerror(err_code)); } session = 0; int* pi = calloc(sizeof(int), 1); *pi = session; if (pthread_create(&system_wideThread[session], 0, system_wider, (void*)pi)) { int err_code = errno; sprintf (line_temp, "*** ERROR: System-wide thread spawn failed […]