C语言中的同步对象及其与数据结构结构的关联



我用C写了一些数据结构,比如线程池使用的任务队列。它与互斥锁和条件变量对象同步。我这样写:

struct task_queue { 
  // some fields
};
typedef struct task_queue task_queue_t; 
static pthread_mutex_t mutex; 
static pthread_cond_t cond; 
task_queue_init(task_queue_t **tq);
task_queue_destroy(task_queue_t *tq); 

但是现在我认为这种方法是相当错误的,因为当我用task_queue_init()在我的程序中创建task_queue结构体的几个实例时,它们将由相同的pthread_mutex_t, pthread_cond_t对象同步。我想我以前在某个地方见过这样的static同步对象声明,并且在我的代码中使用过它。

我的问题是要确保我自己,我计划做正确的方式,即把这个同步对象总是在这个结构task_queue,或其他同步的数据结构结构如下:

struct task_queue { 
   // hitherto fields
   pthread_mutex_t mutex;
   pthread_cond_t cond; 
}
typedef struct task_queue task_queue_t; 
//and initialize/destroy them in 
task_queue_init(task_queue_t **tq); 
task_queue_destroy(task_queue_t *tq); 

也许我应该使用指针互斥,在这个结构体吗?

(事先我应该提到我来自OpenMP和WinAPI,而不是POSIX)

最优解决方案取决于任务的结构、信息传递和运行时行为。

如果我对这个问题的理解是正确的,它的目的是在运行时分配任务队列及其必要的基础设施。在这种情况下,将基础结构放在结构中并不是不正确的。据我所知,在大多数情况下,运行时的分配是作为堆分配完成的,这反过来意味着进程的所有任务对进程堆内存中相同位置的读/写访问。根据访问频率的不同,这可能会也可能不会导致性能问题("虚假共享",经验法则是尽量避免进程全局数据)。

如果(!)另一方面…

a)存在多个(主)任务,每个任务使用自己的任务队列和必要的基础设施

b.1)排队(工作)任务不需要访问其任务队列的基础结构

b.2)或者关于任务队列基础结构的信息在排队(工作)任务和使用(主)任务(task-/thread-private拷贝进出)之间传递

…通过分配using (master)任务的堆栈内存,可以避免一些内存访问问题。在这种情况下,我将使用具有预定义的、足够大小的数组。这可以是一个单一的一维结构数组。也可以使用各种一维数组,每个数组具有相同数量的元素。每个数组保存一种类型信息的元素:一个数组用于任务队列,一个数组用于任务队列的互斥锁,等等。然后通过访问具有相同数组索引的各种数组来访问相同的任务队列及其基础结构。根据具体情况,这在将有关任务队列的信息传入和传出排队(工作)任务时是有利的。

如果您计划在代码中不能保证任务队列仍然存在的地方使用任务队列,那么互斥锁和条件变量不能是成员变量-您必须确保至少它们存在,以便您可以触摸它们

最新更新