艾森伯格-麦奎尔算法分割错误的实现:C中的11

Implementation of Eisenberg-McGuire algorithm segmentation fault: 11 in C

本文关键字:错误 分割 算法 实现 中的 伯格      更新时间:2023-10-16

我试图理解艾森伯格-麦奎尔算法,我找到了这个实现它的程序,但是当我运行该程序时,我遇到了分割错误。

Segmentation fault: 11

这是程序

/* Eisenberg-McGuire algorithm: a software approach to N-process
   mutual exclusion.
   For description of Eisenberg-McGuire algorithm, see page 261 of
   "Concurrent Systems - Operating Systems, Database and Distributed
   Systems: An Inegrated Approach / Jean Bacon -- 2nd Edition".
   Copyrigh (c) 2001 Xiao Zhang */
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
using namespace std;
/**********************************************************************/
/* Eisenberg-McGuire's algorithm for N-process mutual exclusion       */
/**********************************************************************/
class eis_mcg_mutex_t {
private:
    int n;
    enum procphase { out_cr, want_cr, claim_cr } *procphase;
    int turn;
public:
    /* Initialize the mutex data shared by N processes */
    eis_mcg_mutex_t(int nproc) 
    {
        n = nproc;
        procphase = new enum procphase [n];
        srand(time(0));
        turn = (int) (1.0 * n * rand() / (RAND_MAX + 1.0));
        for (int i = 0; i < n; i++) 
            procphase[i] = out_cr;
    }
  /* Entry protocol for process i */
    void mutex_lock(int i) {
        procphase[i] = want_cr;
        int j = turn;
        do 
        {
            while (j != i) 
            {
                if (procphase[j] == out_cr) 
                    j = (j + 1) % n;
                else 
                    j = turn;
            }
            procphase[i] = claim_cr;
            j = (j + 1) % n;
            while (procphase[j] != claim_cr) 
                j = (j + 1) % n;
        } while (!(j == i && (turn == i || procphase[turn] == out_cr)));
        turn = i;
    }
  /* Exit protocol for process i */
    void mutex_unlock(int i) 
    {
        int j = (turn + 1) % n;
        while (procphase[j] == out_cr) 
            j = (j + 1) % n;
        turn = j;
        procphase[i] = out_cr;
    }
};
/**********************************************************************/
/* To test the Eisenberg-McGuire's algorithm, we write a simple       */
/* program that creates N threads (processes) and then has each       */
/* thread increment a global variable `counter' NLOOP times. The      */
/* final value of `counter' is expected to be N * NLOOP.              */
/**********************************************************************/
#define N 4           /* number of threads */
#define NLOOP 1000    /* number of times each thread loops */
int counter;      /* this is cremented by the threads */
eis_mcg_mutex_t counter_in_use(N);
void *doit(void *arg)
{
  int i, val;
  int tid = *(int *)arg;
  /* Each thread fetches, prints and increments the counter NLOOP times.
     The value of the counter should increase monotonically. */
  for (i = 0; i < NLOOP; i++) {
    /* Replace pthread_mutex_lock() with Eisenberg-McGuire's
       enter-critical-section procedure. */
    counter_in_use.mutex_lock(tid);
    /* Here is critical section */
    val = counter;
    counter = val + 1;
    cout << tid << ": " << counter << endl;
    /* Replace pthread_mutex_unlock() with Eisenberg-McGuire's
       leave-critical-section procedure. */
    counter_in_use.mutex_unlock(tid);
  }
  return NULL;
}
int main()
{
  pthread_t tid[N];
  int i;
  for (i = 0; i < N; i++) pthread_create(&tid[i], NULL, doit, (void *)i);
  for (i = 0; i < N; i++) pthread_join(tid[i], NULL);
  return 0;
}

我不明白是什么导致了分段错误。任何帮助,不胜感激。谢谢。

修复了它。

for (i = 0; i < N; i++) pthread_create(&tid[i], NULL, doit, (void *)i);

应该是

for (i = 0; i < N; i++) pthread_create(&tid[i], NULL, doit, (void *)&i);

错过了安曼接线员的地址。

更新:

我现在没有传递地址。

for (i = 0; i < N; i++) pthread_create(&tid[i], NULL, doit, (void *)i);

而在int doit(void *arg)年,改变了int tid = *((int*)(&arg));

它现在运行良好。