C - 如何使我的数据结构实现同步?

时间:2017-04-12 02:32:48

标签: c multithreading data-structures

我有一个我个人实现的数据结构,现在需要跨多个线程使用。

typedef struct 
{
    void** array_of_elements;
    size_t size;
} myStruct;

为简单起见,假设我的数据结构具有以下功能:

// Gets a data element from the structure.
void* get(myStruct *x);
// Prints out all the data elements.
void print(myStruct *x);
// Adds an element into the structure.
void add(myStruct *x, void *to_be_added);

在另一个线程调用get时调用print并不是问题,因为它们都是访问者。但是,getprint在当前正在调用add时无效。反之亦然,如果addget当前正在进行中,则print无效。

所以我将myStruct更改为如下所示:

typedef struct 
{
    void** array_of_elements;
    size_t size;

    // True when a mutator is editing this struct.
    bool mutating;
    // The number of threads currently accessing this struct.
    int accessors;
} myStruct;

现在我的功能如下所示:

void* get(myStruct *x)
{
    // Wait for mutating to end.
    while (x->mutating);
    // Indicate that another accessor is now using this struct.
    x->accessors++;

    // get algorithm goes here

    // Declare we are finished reading.
    x->accessors--;

    return ...
}

// Same as above...
void print(myStruct *x)
...

void add(myStruct *x)
{
    // Wait for any accessors or mutators to finish.
    while (x->mutating || x->accessors > 0);    
    x->mutating = true;

    // add algorithm here

    x->mutating = false;
}

,我认为这种方法存在很多问题,我找不到解决问题的方法:

  • 我的一个同学告诉我使用像这样的while循环会大大减慢线程。
  • 没有队列感。开始等待myStruct完成使用的第一种方法不一定是接下来的方法。
  • 即使我有一个下一个线程的队列数据结构,该数据结构也需要同步,这本身就是一个需要同步数据结构来自我同步的无限循环
  • 我认为有可能在同一纳秒中,一个线程将accessors计数器从0更改为1(意味着他们想要开始阅读),这可能是一个mutator线程看到它的值是0并开始变异。然后,mutator线程和访问者线程将同时进行。
  • 我很确定这个逻辑会导致网格锁定(线程无限地等待彼此)。
  • 除了让它停留在while循环中之外,我不知道如何使某些线程在需要执行此任务时正常睡眠和唤醒。

1 个答案:

答案 0 :(得分:0)

你有正确的想法,只是错误的方法。我不确定您正在编程的操作系统,但是您想要查看mutexsemaphore的概念来执行您想要执行的操作。

在兼容POSIX的Linux / Unix上,您可以查看pthreads:

http://www.cs.wm.edu/wmpthreads.html

在Windows上,您可以查看Critical Sections附近mutex概念的内容:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682530(v=vs.85).aspx

WaitForMultipleObjects或接近semaphore的内容:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx

而且,是的,使用while循环是一个坏主意。在这种情况下,您正在使用所谓的繁忙循环。在这里阅读更多内容:

What is a busy loop?

使用mutexsemaphore,不需要while循环。祝你好运!

相关问题