malloc 失败会导致死锁或竞争条件吗?

标签 c multithreading concurrency malloc deadlock

摘自教科书:

One small tricky issue arises if malloc() happens to fail (a rare case); in this case, the code must also release the lock before failing the insert.

给出的例子:

int List_Insert(list_t *L, int key) {
    pthread_mutex_lock(&L->lock);
    node_t *new = malloc(sizeof(node_t));
    if (new == NULL) {
       perror("malloc");
       pthread_mutex_unlock(&L->lock);
       return -1; // fail
    }
    new->key  = key;
    new->next = L->head;
    L->head   = new;
    pthread_mutex_unlock(&L->lock);
    return 0; // success
}

这会起作用。(认为其他一切都很完美)

如果我这样写,会导致死锁吗?多个线程可以访问共享内存(竞争条件)吗?我试图了解当 malloc 在已获取锁的线程中失败时到底会发生什么。我不需要正确的解决方案,我想知道已获取锁的线程中 malloc 失败的解释/最终结果。假设所有其他功能均已正确实现。

int List_Insert(list_t *L, int key) {
    pthread_mutex_lock(&L->lock);
    node_t *new = malloc(sizeof(node_t));
    new->key  = key;
    new->next = L->head;
    L->head   = new;
    pthread_mutex_unlock(&L->lock);
    return 0; // success
}

最佳答案

malloc() 失败对锁定、数据竞争等没有直接影响。您的文本实际上并未调用 malloc() 失败作为特殊情况;这只是它正在讨论的代码中可能出现的故障模式。

要点是,一旦获取了互斥锁,线程就必须确保释放它,即使发生任何类型的故障也是如此。如果它不这样做,那么此后任何其他线程都将无法获取互斥体;这可能会产生死锁,但实际上是否会产生死锁取决于许多其他因素。

因此,教科书区分了它的好例子和这个糟糕的替代方案:

int List_Insert(list_t *L, int key) {
    pthread_mutex_lock(&L->lock);
    node_t *new = malloc(sizeof(node_t));
    if (new == NULL) {
       perror("malloc");
       // BAD BAD BAD: function exits without unlocking the mutex!!!
       return -1; // fail
    }
    // ...
    pthread_mutex_unlock(&L->lock);
    return 0; // success
}

不言而喻(但无论如何我都会说),如果 malloc() 失败(如返回 NULL 所示),它不会提供任何您可以使用的内存使用。完全忽略检查 malloc() 失败是一个完全不同的问题。

关于malloc 失败会导致死锁或竞争条件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42425767/

相关文章:

.net - .NET 是否具有等效于 Java 的 ConcurrentHashMap 的 Dictionary 实现?

loops - 在迭代过程中同时修改 map 时如何使用RWMutex

c - 如何定义枚举的大小减去一个元素

c - 在 C 中只打印一次

c- 增加数组大小并尝试达到后出现段错误

android - ListView的自定义适配器

c - 这是 3 的输出谁能告诉我怎么做?

multithreading - 我可以安全地对不应该是多线程的东西进行多线程处理吗?

java - 线程利用策略

java - 条件 vs 等待通知机制