Peterson的C语言中的线程并发算法(段错误)

时间:2014-03-07 01:56:07

标签: c multithreading algorithm

嘿伙计我在C中实现Peterson的算法。我有两个函数将由创建的线程执行,一个将1加到变量上,另一个将1减去同一个变量。

程序接收int类型的参数,该整数是我想要创建的线程数的平方根,例如,如果我在终端输入中执行它 ./algorithm 10,将创建10 * 10(10 000)个线程。

如果y类型小于170作为参数,程序运行正常(将创建28900个线程)但是如果我想创建更多,我得到一个段错误,尝试使用“long long int”变量但是不是吗

有一个名为“cont”的计数器,每次cont达到10000时都会打印变量。 变量的最后一个结果还有另一个打印,应始终为0,因为n个线程添加1个,n个线程减1。

我想知道为什么我会收到一个Segment Fault,如果要创建一个线程限制,或者我的代码中有什么内容。

我使用下一个命令运行它只使用一个处理器,因为Peterson的算法只能在单处理器系统上完美运行:

taskset -c 0 ./alg3 100

以下是代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>




long int n;
long int var = 0;
long int cont = 1;
int flag[] = {0, 0};
int turn = 0;

void* sum(void* data) {
    //int n = *((int*)data); 
    int i;

    turn = 2;
    flag[0] = 1;
    while (turn == 2 && flag[1]);
    cont++;
    var += 1;
    if (cont == 10000) {
        printf("varsum=%ld\n", var);
        cont = 1;
    }

    flag[0] = 0;
}

void* rest(void* data) {
    //int n = *((int*)data); 
    int i;
    turn = 1;
    flag[1] = 1;
    while (turn == 1 && flag[0]);
    cont++;
    var -= 1;
    if (cont == 10000) {
        printf("varres=%ld\n", var);
        cont = 1;
    }

    flag[1] = 0;

}

main(int argc, char *argv[]) {
    long int i;
    n = atoi(argv[1]);
    n *= n; //n*n is the actual number of threads that will be created

    pthread_t tid[n];


    for (i = 0; i < n; i++) {
        pthread_create(&tid[i], NULL, sum, NULL);
        //cont++;

    }
    for (i = 0; i < n; i++)
        pthread_join(tid[i], NULL);

    for (i = 0; i < n; i++) {
        pthread_create(&tid[i], NULL, rest, NULL);
        //cont++;

    }
    for (i = 0; i < n; i++)
        pthread_join(tid[i], NULL);

    printf("main() reporting that all %ld threads have terminated\n", i);
    printf("variable=%ld\n", var);

} /* main */

2 个答案:

答案 0 :(得分:1)

至少向pthread_create()添加错误检查,以避免将无效的pthread_t变量传递给pthread_join()

int main(int arc, char ** argv)
{

  ...

  pthread_t tid[n];
  int result[n];


  for (i = 0; i < n; i++) {
    result[i] = errno = pthread_create(&tid[i], NULL, sum, NULL);
    if (0 != errno) {
      perror("pthread_create() failed");
    }
  }

  for (i = 0; i < n; i++) {
    if (0 == result(i]) {
      errno = pthread_join(tid[i], NULL);
      if (0 != errno) {
        perror("pthread_join() failed");
      }
    }
  }

  ...

此外,始终保护对写入count的变量的并发访问权限。为此,请使用pthread_mutex_t变量。

答案 1 :(得分:1)

首先,当然创建线程是有限的。它取决于每个线程和硬件的堆栈大小,详细建议google它... 段故障原因: 你没有检查函数pthread_create的返回值,当'n'足够大时,pthread_create将失败,那么pthread_join可能会使用不存在的thread_t作为第一个输入参数。以下代码(从您的示例中更改)可以测试您可以创建的线程数。

int rc = 0, thread_num = 0;
    for (i = 0; i < n; i++) {
        rc = pthread_create(&tid[i], NULL, sum, NULL);
        if (rc)
        {
            printf("pthread_crate failed, thread number: %d, error code: %d\n", thread_num, rc);
        }
        thread_num++;
    }
    printf("created %d threads.\n", thread_num);