Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 并发访问和无堆对象_C_Multithreading_Concurrency - Fatal编程技术网

C 并发访问和无堆对象

C 并发访问和无堆对象,c,multithreading,concurrency,C,Multithreading,Concurrency,这个问题可能是这个问题的一个子问题 另一个问题有待设计,这个问题更具体 struct ds { int x,y,z; pthread_mutex_t mutex; }; 我需要一个确定性的解决方案,通过它我可以同时访问1个ds类型的对象并释放它 限制: 可以将互斥体设为指针,但不能将其从对象中取出 真正的问题是: 持有锁无法释放内存,因为锁占用的内存也会丢失 我读过很多关于参考文献计数的论文和文章,但每一篇都在ds外有一把锁。我想要一个解决方案,可以在ds中保留锁或对

这个问题可能是这个问题的一个子问题

另一个问题有待设计,这个问题更具体

struct ds
{
   int x,y,z;       
   pthread_mutex_t mutex;
};
我需要一个确定性的解决方案,通过它我可以同时访问1个ds类型的对象并释放它

限制:

  • 可以将互斥体设为指针,但不能将其从对象中取出
  • 真正的问题是:

    持有锁无法释放内存,因为锁占用的内存也会丢失

    我读过很多关于参考文献计数的论文和文章,但每一篇都在ds外有一把锁。我想要一个解决方案,可以在ds中保留锁或对锁的引用。

    既然你说“互斥体可以是指针”,你可以这样做:

    struct ds { pthread_mutex_t * mutex; /* ... */ };
    
    struct ds * create_ds()
    {
        struct ds * p = calloc(1, sizeof(struct ds));
        pthread_mutex_t * q = malloc(sizeof(pthread_mutex_t));
        pthread_mutex_init(q, NULL);
        ds->mutex = q;
        return p;
    }
    
    void free_ds(struct ds * p)
    {
        pthread_mutex_t * q = p->mutex;
        pthread_mutex_lock(q);
        free(p);
        pthread_mutex_unlock(q);
        pthread_mutex_destroy(q);
        free(q);
    }
    
    不过,在我看来,销毁对象并不真正符合并发访问/同步习惯用法。如果你破坏了一些东西,它就不在了,所以所有的线程都会受到影响。线程如何知道给定的
    ds
    指针是否仍然指向有效的对象

    相反,您可能应该在某个地方有一个
    ds
    对象的集合,对该集合的插入/擦除访问应该有自己的、独立的、集合范围的互斥体。每当线程想要获取对集合中某个对象的引用时,它都应该在互斥体的保护下进行,并且集合应该知道谁当前持有引用。

    既然您说“互斥体可以是指针”,您可以这样做:

    struct ds { pthread_mutex_t * mutex; /* ... */ };
    
    struct ds * create_ds()
    {
        struct ds * p = calloc(1, sizeof(struct ds));
        pthread_mutex_t * q = malloc(sizeof(pthread_mutex_t));
        pthread_mutex_init(q, NULL);
        ds->mutex = q;
        return p;
    }
    
    void free_ds(struct ds * p)
    {
        pthread_mutex_t * q = p->mutex;
        pthread_mutex_lock(q);
        free(p);
        pthread_mutex_unlock(q);
        pthread_mutex_destroy(q);
        free(q);
    }
    
    不过,在我看来,销毁对象并不真正符合并发访问/同步习惯用法。如果你破坏了一些东西,它就不在了,所以所有的线程都会受到影响。线程如何知道给定的
    ds
    指针是否仍然指向有效的对象


    相反,您可能应该在某个地方有一个
    ds
    对象的集合,对该集合的插入/擦除访问应该有自己的、独立的、集合范围的互斥体。每当线程想要获取对集合中某个对象的引用时,它都应该在互斥锁的保护下进行,集合应该知道当前谁在持有引用。

    free_ds中的代码仍然不安全:如果互斥体销毁是在另一个具有相同
    struct ds
    实例地址的线程试图访问它时进行的,该怎么办?@AlexeyKukanov:正如我在最后两段中所说的,我不认为可以使用元素互斥来防止容器变异,因此释放元素确实应该由其他人来保护,而不是元素本身。@KerrekSB我也认为,无论互斥体或其指针是否在数据结构中,这个问题都无法解决。我认为可能会有一些解决方案使用原子CAS指令/危险指针,正如原始问题中有人建议的那样。@AlexeyKukanov我希望我们可以使用引用计数来解决一些解决方案。我们可以通过确保没有人可以进行非法访问,自由约束用户以特定方式使用ds。解决办法对我来说并不明显,我的希望近乎悲观!
    free_ds
    中的代码仍然是不安全的:如果互斥体销毁是在另一个具有相同
    struct ds
    实例地址的线程试图访问它时进行的呢?@AlexeyKukanov:正如我在最后两段中所说的,我认为不能使用元素互斥体来防止容器突变,所以释放一个元素确实应该由其他人来保护,而不是元素本身。@KerrekSB我也认为这个问题是无法解决的,无论互斥体或它的指针是否在数据结构中。我认为可能会有一些解决方案使用原子CAS指令/危险指针,正如原始问题中有人建议的那样。@AlexeyKukanov我希望我们可以使用引用计数来解决一些解决方案。我们可以通过确保没有人可以进行非法访问,自由约束用户以特定方式使用ds。解决办法对我来说并不明显,我的希望近乎悲观!我想问题可以归结为确保在执行free时没有对对象的外部引用。因此,如果外部引用是指针,我们将需要在ds之外的另一个锁来确保对象没有消失。这就是他们在boost中发明shared_ptr的原因。我想问题可以归结为确保在执行free时没有对对象的外部引用。因此,如果外部引用是指针,我们将需要在ds之外的另一个锁来确保对象没有消失。这就是他们在boost中发明共享ptr的原因。