Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Multithreading_Pthreads - Fatal编程技术网

C 概念线程问题

C 概念线程问题,c,multithreading,pthreads,C,Multithreading,Pthreads,我正在一些线程中生成从1到N的数字散列(MD5)。根据散列的第一个字母,生成散列的数字存储在数组中。例如,数字1产生c4ca4238a0b923820dcc509a6f75849b,数字2产生c81e728d9d4c2f636f067f89cc14862c,因此它们存储在以“c”开头的特定哈希数组中 问题是我需要生成从低到高排序的数据。在序列完成后对它们进行排序非常昂贵,N可以大到2^40。由于我使用线程,排序从来不会自然进行。例如,一个线程可以生成数字12(c20ad4d76fe97759aa

我正在一些线程中生成从1到N的数字散列(MD5)。根据散列的第一个字母,生成散列的数字存储在数组中。例如,数字1产生c4ca4238a0b923820dcc509a6f75849b,数字2产生c81e728d9d4c2f636f067f89cc14862c,因此它们存储在以“c”开头的特定哈希数组中

问题是我需要生成从低到高排序的数据。在序列完成后对它们进行排序非常昂贵,N可以大到2^40。由于我使用线程,排序从来不会自然进行。例如,一个线程可以生成数字12(c20ad4d76fe97759aa27a0c99bff6710)的散列并将其存储在“c”数组中,另一个线程则生成数字8(c9f0f895fb98ab9159f51fd0297e236d)的散列并将其存储在数字12之后的“c”数组中

我不能简单地验证数组上的最后一个数字,因为只要线程在运行,它们之间的距离就可能非常远

这个线程问题有什么解决方案吗?任何比在所有线程完成后订购阵列更快的解决方案都非常好

我正在用C实现这个


谢谢大家!

既然您提到了pthreads,我就假设您使用的是gcc(不一定是这样,但可能是这样)。您可以使用
\uuuu sync\u fetch\u和\u add
获取数组末尾的值,并在一个原子操作中将一个值添加到数组中。它会像下面这样:

insertAt = __sync_fetch_and_add(&size[hash], 1);
arrayOfInts[insertAt] = val;
您将遇到的唯一问题是是否需要调整数组大小(不确定是否事先知道数组大小)。为此,您需要一个锁(最有效的是每个数组一个锁),在重新分配数组时以独占方式锁定,在插入时以非独占方式锁定。特别是,这可以通过以下函数实现(假定程序员不释放解锁的锁):


不是每个前缀都有一个数组(例如“c”),而是每个线程都有一个前缀数组。每个线程只插入到它自己的数组中,因此它将始终按递增顺序插入数字,并且各个线程数组将保持排序


然后可以在流程结束时快速(
O(N)
)合并数组,因为各个数组都将被排序。这也将加快创建过程,因为您不需要在阵列周围进行任何锁定。

我无法理解您的要求。你有16个东西的数组吗(不确定它们是整数还是什么)。您是否正在尝试基于MD5哈希创建哈希表?至此,我有16个数组,每个数组都有很多整数。正如我在问题中所解释的那样,每个整数的散列将存储在哪个数组中。@CrazyCasta,是的,一种基于MD5散列的散列表。您可以让每个线程对自己的结果进行排序,然后在最后合并结果。合并应该比较快。@VaughnCato,每个线程在完成所有哈希生成后对一个数组进行排序?这是个好主意!多谢各位@caf@FredericoSchardong:更好的是,您可以在线程之间预先分配要散列的输入编号(例如,线程1散列编号0-1023,线程2散列编号1024-2047…),这样您就可以通过连接数组来组合数组。
// Flag 2 indicates exclusive lock
void lockExclusive(int* lock)
{
    while(!__sync_bool_compare_and_swap(lock, 0, 2));
}

void releaseExclusive(int* lock)
{
    *lock = 0;
}

// Flag 8 indicates locking
// Flag 1 indicates non-exclusive lock
void lockNonExclusive(int* lock, int* nonExclusiveCount)
{
    while((__sync_fetch_and_or(lock, 9) & 6) != 0);
    __sync_add_and_fetch(nonExclusiveCount, 1);
    __sync_and_and_fetch(lock, ~8);
}

// Flag 4 indicates unlocking
void releaseNonExclusive(int* lock, int* nonExclusiveCount)
{
    while((__sync_fetch_and_or(lock, 4) & 8) != 0);
    if(__sync_sub_and_fetch(nonExclusiveCount) == 0);
        __sync_and_and_fetch(lock, ~1);
    __sync_and_and_fetch(lock, 4);
}