C-保护共享数据并共享相同的堆栈



如何保护共享资源?需要确定哪种代码使用共享资源并保护它们。我猜测POP和PUSH资源是共享的。因此,为了保护他们,我会将这些功能放在保护标签下:就像有私人:公共:我还如何制作创建的200个线程共享相同的堆栈。更新:我的教授说,顶部是共享资源。

/*
* Stack containing race conditions
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
// Linked list node
typedef int value_t;
typedef struct Node
{
  value_t data;
  struct Node *next;
} StackNode;

// Stack function declarations
void push(value_t v, StackNode **top);
value_t pop(StackNode **top);
int is_empty(StackNode *top);
pthread_mutex_t mutex; 
//--Tom  This is the wrong function signature for thread entry functions
void *testStack(void *arg)
{
  StackNode *top = NULL;
  for (int i = 0; i < 500; i++)
  {
     pthread_mutex_lock(&mutex);
    // --Tom  Mix these up a bit more
    push(5, &top);
    pop(&top);
    push(6, &top);
    pop(&top);
    push(15, &top);

    pop(&top);
    pthread_mutex_unlock(&mutex);
  }
  pthread_exit(0);
}


int main(int argc, char *argv[])
{
  //--Tom   defining mutex on the stack is not a good choice.  Threads don't share data on the stack
  pthread_mutex_init(&mutex, NULL);


  for (int i = 0; i < 200; i++)
  {
    pthread_t tid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    //--Tom this is the wrong place to lock.  Need something that sourounds only the code accessing shared resources
    //--Tom argv[1] in not what yo want to pass the thread
    pthread_create(&tid, &attr, testStack, NULL);
    //--Tom  You are not allowingthe threads to run in parallel

  }
  return 0;
}
// Stack function definitions
void push(value_t v, StackNode **top)
{
  //--Tom  you have not identified the critical lines of code and protected them
  StackNode *new_node = malloc(sizeof(StackNode));
  new_node->data = v;
  new_node->next = *top;
  *top = new_node;
}
value_t pop(StackNode **top)
{
  //--Tom  you have not identified the critical lines of code and protected them
  if (is_empty(*top))
    return (value_t)0;
  value_t data = (*top)->data;
  StackNode *temp = *top;
  *top = (*top)->next;
  free(temp);
  return data;
}
int is_empty(StackNode *top)
{
  //--Tom  you have not identified the critical lines of code and protected them
  if (top == NULL)
    return 1;
  else
    return 0;
}

如何使我创建的200个线程共享相同的堆栈

第一个可能性是具有全局变量StackNode *top;,但是如果要重用不同堆栈的相同代码,则是一个问题。

第二个是在 main 中具有该变量局部性,并在参数中给出其地址时,当您启动一个新线程代替 null 您当前有,然后 testack的实际上是a stacknode **


在呼叫 push/pop 之前,请勿管理互斥品,在功能中进行管理,否则忘记保护的风险很高。因此,mutext不会出现在 testack 中。在这种情况下,请参阅我对is_empty

的评论
int is_empty(StackNode *top)
{
  //--Tom  you have not identified the critical lines of code and protected them
  if (top == NULL)
    return 1;
  else
    return 0;
}

为什么如此复杂?

int is_empty(StackNode *top)
{
  //--Tom  you have not identified the critical lines of code and protected them
  return (top == NULL);
}

是的,堆栈没有修改,也不会看内部,因此对于空视图而言,并不是关键的

/* ptop is a StackNode ** */
if (!is_empty(*ptop)) 
  // here the stack can be empty anyway because an other thread got the CPU
  pop(ptop);

如果您想提供一个可以在其中进行多个操作的保护区域

),因为它也将在所谓的函数内部锁定/解锁, mutex 需要递归(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP


隐藏 mutex 将其分组,然后在另一个结构中 top ,该允许不共享Mutex的不同堆栈

最新更新