首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程条件变量和互斥变量,程序具有死锁。

线程条件变量和互斥变量,程序具有死锁。
EN

Stack Overflow用户
提问于 2015-04-14 03:39:47
回答 3查看 664关注 0票数 1

我的多线程代码出了问题,有一个死锁,但我不知道如何修复它,因为我对线程非常陌生。

下面的代码显示了一个名为“空闲”的函数,该函数正在等待一个模拟进程被放置在一个readyqueue上,而push函数应该将该进程放置在队列中,然后发出信号,表示有一个可以调度的进程。

以下是导致死锁的两个函数:

代码语言:javascript
复制
void push(pcb_t *pcb) {
    pthread_mutex_lock(&queue_mutex);
    if (head == NULL) {
        head = pcb;
        tail = pcb;
    } else {
        pcb_t *old_tail = tail;
        tail = pcb;
        old_tail->next = tail;
    }
    pthread_cond_signal(&proc_ready);
    pthread_mutex_unlock(&queue_mutex);
}
extern void idle(unsigned int cpu_id)
{
    pthread_mutex_lock(&queue_mutex);

    while(head == NULL) {
        pthread_cond_wait(&proc_ready, &queue_mutex);
    }
    pthread_mutex_unlock(&queue_mutex);
    schedule(cpu_id);

    /*

     * idle() must block when the ready queue is empty, or else the CPU threads
     * will spin in a loop.  Until a ready queue is implemented, we'll put the
     * thread to sleep to keep it from consuming 100% of the CPU time.  Once
     * you implement a proper idle() function using a condition variable,
     * remove the call to mt_safe_usleep() below.
     */
}

以下是gdb的回溯:

代码语言:javascript
复制
Thread 2 (Thread 0xb7df7b40 (LWP 3443)):
#0  0xb7fdd424 in __kernel_vsyscall ()
No symbol table info available.
#1  0xb7fb59e2 in __lll_lock_wait ()
    at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/lowlevellock.S:144
No locals.
#2  0xb7fb1267 in _L_lock_847 () from /lib/i386-linux-gnu/libpthread.so.0
No symbol table info available.
#3  0xb7fb10a0 in __GI___pthread_mutex_lock (mutex=0x804c75c <queue_mutex>)
    at ../nptl/pthread_mutex_lock.c:79
        __PRETTY_FUNCTION__ = "__pthread_mutex_lock"
        type = 0
        id = <optimized out>
#4  0x080489d9 in idle (cpu_id=0) at student.c:116
No locals.
#5  0x08048f65 in simulator_cpu_thread (cpu_id=0) at os-sim.c:259
        state = CPU_IDLE
#6  0x08049b4a in simulator_cpu_thread_func (data=0x0) at os-sim.c:618
No locals.
#7  0xb7faef70 in start_thread (arg=0xb7df7b40) at pthread_create.c:312
        __res = <optimized out>
        pd = 0xb7df7b40
        now = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {-1208217600, -1210090688, 4001536, 
                -1210092504, -193645269, -1085428949}, mask_was_saved = 0}}, priv = {
            pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, 
              canceltype = 0}}}
        not_first_call = <optimized out>
        pagesize_m1 = <optimized out>
        sp = <optimized out>
        freesize = <optimized out>
---Type <return> to continue, or q <return> to quit---
        __PRETTY_FUNCTION__ = "start_thread"
#8  0xb7ee5bee in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129
No locals.

Thread 1 (Thread 0xb7df8700 (LWP 3439)):
#0  0xb7fdd424 in __kernel_vsyscall ()
No symbol table info available.
#1  0xb7fb59e2 in __lll_lock_wait ()
    at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/lowlevellock.S:144
No locals.
#2  0xb7fb1267 in _L_lock_847 () from /lib/i386-linux-gnu/libpthread.so.0
No symbol table info available.
#3  0xb7fb10a0 in __GI___pthread_mutex_lock (mutex=0x804c75c <queue_mutex>)
    at ../nptl/pthread_mutex_lock.c:79
        __PRETTY_FUNCTION__ = "__pthread_mutex_lock"
        type = 0
        id = <optimized out>
#4  0x0804886f in push (pcb=0x804c660 <processes>) at student.c:42
No locals.
#5  0x08048acb in wake_up (process=0x804c660 <processes>) at student.c:205
No locals.
#6  0x08049a14 in simulate_io () at os-sim.c:590
        completed = 0x804d0f8
        pcb = 0x804c660 <processes>
#7  0x08048e0f in simulator_supervisor_thread () at os-sim.c:189
No locals.
#8  0x08048dcc in start_simulator (new_cpu_count=1) at os-sim.c:161
        n = 1
        __PRETTY_FUNCTION__ = "start_simulator"
#9  0x08048ba8 in main (argc=2, argv=0xbffff284) at student.c:240
        cpu_count = 1
        __PRETTY_FUNCTION__ = "main"

编辑: pop函数,它也使用queue_mutex

代码语言:javascript
复制
pcb_t * pop() {
    pcb_t *pcb = NULL;
    pthread_mutex_lock(&queue_mutex);
    if (head == NULL) {
        return NULL;
    } else if (head == tail) {
        pcb = head;
        head = NULL;
        tail = NULL;
    } else {
        pcb = head;
        head = head->next;
    }
    pthread_mutex_unlock(&queue_mutex);
    pcb->next = NULL;
    return pcb;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-14 03:58:32

在头==为空的情况下,pop函数不解锁互斥锁。

票数 3
EN

Stack Overflow用户

发布于 2015-04-14 04:04:55

在控制head在null函数中是否为pop之后,您的互斥对象应该以一种适当的方式被锁定,否则它就会被阻塞。而且,pthread_cond_signal函数可以由线程调用,无论它当前是否拥有调用pthread_cond_wait的线程在等待期间与条件变量相关联的互斥对象;但是,如果需要可预测的调度行为,则调用pthread_cond_signal的线程锁定该互斥量。

票数 0
EN

Stack Overflow用户

发布于 2015-04-14 04:02:54

您的空闲函数锁定互斥锁,然后在您的上自旋锁。然后,当调度程序想要执行时,允许执行push函数,但是push函数做的第一件事就是尝试获取互斥。不幸的是,互斥锁已经被空闲线程所拥有。因此,push线程阻塞,等待释放互斥,这将永远不会发生,因为空闲函数正在对进行自旋锁定。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29618756

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档