Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C-使用PThreads时更快地锁定整数_C++_C_Multithreading_Io_Pthreads - Fatal编程技术网

C++ C-使用PThreads时更快地锁定整数

C++ C-使用PThreads时更快地锁定整数,c++,c,multithreading,io,pthreads,C++,C,Multithreading,Io,Pthreads,我有一个计数器,多个线程使用它来写入数组中的特定元素。这是我到目前为止所拥有的 int count = 0; pthread_mutex_t count_mutex; void *Foo() { // something = random value from I/O redirection pthread_mutex_lock(&count_mutex); count = count + 1; currentCount = count; pth

我有一个计数器,多个线程使用它来写入数组中的特定元素。这是我到目前为止所拥有的

int count = 0;
pthread_mutex_t count_mutex;

void *Foo()
{
    // something = random value from I/O redirection
    pthread_mutex_lock(&count_mutex);
    count = count + 1;
    currentCount = count;
    pthread_mutex_unlock(&count_mutex);
    // do quick assignment operation. array[currentCount] = something
}
main()
{
    // create n pthreads with the task Foo
}
问题是它的速度太慢了。我接受一个整数文件作为I/O重定向,并将它们写入数组。似乎每个线程都要花费大量时间等待锁被移除。有没有更快的方法增加计数器


注意:我需要保持数字的顺序,这就是为什么我必须使用计数器,而不是给每个线程一个特定的数组块来写入

一种选择是在将批处理应用于受保护的资源之前,在本地某处对更改进行批处理

例如,让每个线程收集十条信息(如果它在收集十条信息之前就用完了,则会更少),然后修改
Foo
以获取长度和数组-这样,您就可以摊销锁定的成本,使其更加有效

我也会非常谨慎地做:

// do quick assignment operation. array[currentCount] = something

在受保护区域之外-这是灾难的原因,因为另一个线程可能会从您下面更改
currentCount
。如果它是一个局部变量,这不是问题,因为每个线程都有自己的副本,但代码中不清楚该变量的作用域。

好的,一个选项是在将批处理应用于受保护的资源之前,在某个地方对更改进行本地批处理

例如,让每个线程收集十条信息(如果它在收集十条信息之前就用完了,则会更少),然后修改
Foo
以获取长度和数组-这样,您就可以摊销锁定的成本,使其更加有效

我也会非常谨慎地做:

// do quick assignment operation. array[currentCount] = something

在受保护区域之外-这是灾难的原因,因为另一个线程可能会从您下面更改
currentCount
。如果它是一个局部变量,这不是问题,因为每个线程都有自己的副本,但代码中不清楚该变量的作用域。

您需要使用联锁。查看windows上的函数,或者苹果的函数,或者linux上的函数


如果您有一个支持C++11的编译器,您甚至可以使用。

您需要使用联锁。查看windows上的函数,或者苹果的函数,或者linux上的函数



如果您有一个支持C++11的编译器,您甚至可以使用。

currentCount是一个局部变量。@user1002479:因此,您可以忽略我的警告。currentCount是一个局部变量。@user1002479:因此,您可以忽略我的警告。我考虑过原子,但我不确定它们是否解决了问题。它们使单个操作原子化,例如
x++
,但这个问题有两个操作:
x++
y=x
。这两个线程之间可能存在线程切换,这将导致两个线程都写入同一数组索引。由于currentCount是本地的,
currentCount=++count
其中
++count
是原子的,这将是完美的…@paxdiablo如果CPU有CAS2类指令,则可以更改2个值。@toby,不要错误地认为原子性在C语句级别工作:-)即使
count++
是原子的,将值赋值给
currentCount
也不是同一个原子的一部分。换句话说,
count
可以在赋值之前再次递增(通过另一个线程)。@paxdiablo我很清楚这一点。我建议使用一个原子增量函数,它返回递增到的值(正如
++
所做的那样)。我的措辞有点模棱两可——也许“where++is atomic”应该是“if++are atomic”。我考虑过原子学,但我不确定它们是否解决了这个问题。它们使单个操作原子化,例如
x++
,但这个问题有两个操作:
x++
y=x
。这两个线程之间可能存在线程切换,这将导致两个线程都写入同一数组索引。由于currentCount是本地的,
currentCount=++count
其中
++count
是原子的,这将是完美的…@paxdiablo如果CPU有CAS2类指令,则可以更改2个值。@toby,不要错误地认为原子性在C语句级别工作:-)即使
count++
是原子的,将值赋值给
currentCount
也不是同一个原子的一部分。换句话说,
count
可以在赋值之前再次递增(通过另一个线程)。@paxdiablo我很清楚这一点。我建议使用一个原子增量函数,它返回递增到的值(正如
++
所做的那样)。我的措辞有点模棱两可——也许“where++is atomic”应该是“if++are atomic”。如果我理解你:你有一个充满整数的管道,你从管道中读取并将整数写入数组。为什么这里需要线程?我想您可以使用
sem_post
作为原子计数器,但不幸的是,您无法在post操作中原子地读取信号量的旧/新值(如果我理解你的话:你有一个充满整数的管道,你正在从管道中读取并将整数写入数组。为什么我们需要线程?我想你可以使用
sem_post
作为原子计数器,但不幸的是,你不能在post操作中原子地读取信号量的旧/新值(