pthreads mutex没有全局变量,只返回thread_struct中的数组

时间:2017-03-08 12:13:35

标签: c multithreading pthreads mutex

大家再一次!

我正在实现一个计算函数,它运行一大堆数字,因此应该切成所有由单线程计算的小片段。使用少于8个线程& dividable by 2运行okayish(小错误,使用一个线程,所以n_threads = 1,给出正确的结果!)。

问题:“所以我想知道如果我从不访问全局变量,是否需要互斥锁?”

解释现状:我有double sum然后我创建线程并按部分运行数组计算。 最后,我拿出所有部分金额,并将它们加到主计划中的总和中。然后我添加了数组的其余部分,没有分成线程(例如,在总数组长度为10和4个线程的情况下:这将为线程提供8个数组元素,另外2个必须另外计算) 。我担心,这似乎不是正确的方法。我还没有深入到这个主题,所以我不确定是否必须在某个地方锁定一些访问主程序中的总和。

主码:

  double sum = 0;
  // arr, p and n_threads are given into this as input to a function

  pthread_t threads[n_threads];
  struct thread_input thread_args[n_threads];
  int thread_size = total_elemts/n_threads;

 for (int t = 0; t < n_threads; t++){
    thread_args[t].tid = t;
    thread_args[t].start = t*thread_size;
    thread_args[t].end = ((t+1)*thread_size)-1;
    thread_args[t].arr = arr;
    thread_args[t].p = p;
    thread_args[t].part_sum = 0;
    pthread_create(&threads[t], NULL, thread_number, (void*) &thread_args[t]);
   }

 for (int t = 0; t < n_threads; t++){
    pthread_join(threads[t], NULL);
    printf("thread %d %15.10lf\n", t, thread_args[t].part_sum);
    sum += thread_args[t].part_sum;
 }
return sum;

number_thread:

void* thread_number(void* arg){
    struct thread_input *param = (struct thread_input*)arg;

    int i;
    for(i = param->start; i <= param->end; i++){
      param->part_sum += Func1(param->arr[i]);
    }

    for(i = param->start; i <= param->end-1; i+=2){
      param->part_sum += Func2(param->arr[i], param->arr[i+1]);
    }

    for(i = param->start; i <= param->end-3; i+=4){
      param->part_sum += Func3(&param->arr[i], param->p);
    }
    return NULL;
}

没有锁可以没关系,还是我错过了其他的东西? 谢谢大家!

2 个答案:

答案 0 :(得分:2)

pthread_join()由POSIX(基本定义,4.12内存同步,POSIX在http://pubs.opengroup.org/onlinepubs/9699919799/提供)指定,以使内存与其他线程同步,所以不,你不需要互斥锁,thread_args[t].part_sum之后thread_number() pthread_join()的分配对On Error Resume Next Dim cn As ADODB.Connection, rs As ADODB.Recordset, r As Long Set cn = New ADODB.Connection cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Jet OLEDB:Database Password=((*$%&)^#^@; Data Source=C:\z.mdb;" Set rs = New ADODB.Recordset rs.Open "Marvin", cn, adOpenKeyset, adLockOptimistic, adCmdTable With rs .AddNew ' create a new record ' add values to each field in the record .Fields("name") = Range("D3").Value .Fields("field2") = Range("D4").Value .Fields("field3") = Range("D6").Value .Fields("field4") = Range("D7").Value .Update ' stores the new record End With rs.Close Set rs = Nothing cn.Close Set cn = Nothing On Error GoTo 0 MsgBox "Summary Added Successfully.", vbInformation, "Marvin Adams:" 之后的主代码可见。

答案 1 :(得分:1)

不需要锁定,因为 sum 只能在代码的序列部分中访问。

结果中的小误差/变化很可能源于更改求和的顺序,即当您在单个线程中累加总和,并且总和的值变大时,可能会在数字上忽略小的附加值,这可能会累积到一个重大错误。总和部分和首先缓解了这个问题,因此,多线程结果可能更准确。

如果您对代码中的变量进行适当的多线程访问存在疑问,可以考虑在启用thread sanitizer的情况下编译和运行该程序。

作为旁注,在示例代码中没有为成员 param-&gt; buf 分配任何内容。