c - 保护共享数据并共享同一堆栈

标签 c pthreads

如何保护共享资源?需要识别哪些代码行使用了共享资源并保护它们。我的猜测是弹出和推送资源是共享的。因此,为了保护它们,我会将这些函数放在保护标签下:就像有 private: 和 public: 一样?还有如何让我创建的 200 个线程共享同一个堆栈。更新:我的教授说 top 是共享资源。

/*
* 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;
}

最佳答案

how to I make the 200 threads that I created share the same stack

第一种可能性是使用全局变量StackNode *top;,但如果您想为不同的Stack重用相同的代码,这是一个问题。

第二种方法是将该变量放在main中,并在启动新线程时在参数中给出其地址来代替NULL em> 你目前拥有,那么 testStackarg 实际上是一个 StackNode **

<小时/>

不要在调用push/pop之前/之后管理互斥体,而是在函数内部管理它,否则有很高的风险忘记保护。因此互斥文本不会出现在 testStack 中。在这种情况下警告,请参阅我关于 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);

如果您想提供一个可以执行多项操作的保护区域,则必须使用相同的互斥体来完成(可能被函数regionEnterregionExit隐藏) )并且因为它也会在被调用函数内部锁定/解锁,所以互斥体需要递归(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)

<小时/>

将互斥体和顶部分组隐藏在另一个结构中可能会很有趣,这样就可以不共享不同堆栈的互斥体

关于c - 保护共享数据并共享同一堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55067862/

相关文章:

multithreading - sem_init() 导致 SEGV

c++ - 在 main 之前未调用 WinMain(C/C++ 程序入口点问题)

c - OpenMP 无法在 C 语言中工作

objective-c - OS X(Cocoa 等)创建可取消周期性操作的惯用方法

ubuntu - Linux中XAMPP中的Pthreads

c++ - 无法理解 pthread 行为

c - 制作菜单驱动程序,错误

c - 在没有任何警告的情况下转发定义结构和类型

C简单字符串程序无法编译

c - pthread 数组 - 线程是否仍处于事件状态?