为什么我的互斥锁不授予独占访问权限?

问题描述 投票:0回答:1

我的 C 程序有三个线程

A
B
C
,它们共享一些缓冲区。每个缓冲区都由互斥体保护,每个线程在写入/读取缓冲区之前必须锁定互斥体。

A
写入缓冲区,
B
C
读取缓冲区。 main 函数创建
A
,等待直到用
pthread_mutex_lock()
锁定第一个缓冲区,然后创建
B
C
,以便缓冲区始终在读取之前写入。

  • main.c

#define mutex_lock(mutex, buff_num)        log("wait on buff[%d]\n", buff_num);  \
                                           printf("pthread_mutex_lock returns %d\n", pthread_mutex_lock(mutex));   \
                                           log("buff[%d] locked\n", buff_num)
    
#define mutex_unlock(mutex, buff_num)      log("releasing buff[%d]\n", buff_num); \
                                           pthread_mutex_unlock(mutex);           \
                                           log("buff[%d] released\n", buff_num)

...
typedef struct
{
    pthread_mutex_t  lock;
    char             data[MAX_DATA_LENGTH];
} buff_t;

uint8_t A_thread_ready = 0;
buff_t buff[NUM_BUFF];
...

int main()
{
    ...
    for(int i=0; i<NUM_BUFF; i++)
    {
        if (pthread_mutex_init(&buff[i].lock, NULL) != 0)
        {
            pthread_exit(NULL);
        }
    }
    ...
    status = pthread_create(&tid[0], NULL, &A_thread, NULL);
    if ( 0 == status)
    {
        break;
    }

    do
    {
        nanosleep(&t1, &t2);
    } while (0 == A_thread_ready);

    status = pthread_create(&tid[1], NULL, &B_thread, NULL);
    if ( 0 == status)
    {
        break;
    }
    ...
}
  • a.c
...

extern uint8_t A_thread_ready;
extern buff_t buff[NUM_BUFF];

...

void* A_thread(void* arg)
{
    uint8_t write_buff = 0;
    ...
    buff_p = &(buff[write_buff]);
    mutex_lock(&buff_p->lock, write_buff);
    A_thread_ready = 1;
    while(1)
    {
        ...
        mutex_unlock(&buff_p->lock, write_buff);
        write_buff++;
        write_buff %= NUM_BUFF;
        buff_p = &(buff[write_buff]);
        mutex_lock(&buff_p->lock, write_buff);
        ...
    }
    ...
}
  • b.c
...

extern buff_t buff[NUM_BUFF];

...

void* B_thread(void* arg)
{
    uint8_t read_buff = 0;
    ...
    buff_p = &(buff[read_buff]);
    mutex_lock(&buff_p->lock, read_buff);

    while(1)
    {
        ...
        mutex_unlock(&buff_p->lock, read_buff);
        read_buff++;
        read_buff %= NUM_BUFF;
        buff_p = &(buff[read_buff]);
        mutex_lock(&buff_p->lock, read_buff);
        ...
    }
    ...
}

当线程锁定互斥锁时,三个日志总是连续出现三行:宏中

printf()
之前等待互斥锁的日志,
pthread_mutex_lock()
返回0(表示成功),以及显示缓冲区的日志
printf()
后立即锁定。

然而,当运行程序时,从打印的日志来看,对缓冲区的访问似乎并不过分:在

A

 锁定缓冲区后,
B
 能够锁定同一个缓冲区。然后它做了一些事情,并释放了缓冲区。一段时间后
A
释放了这个缓冲区。我还应该检查什么来找出此问题的原因?

c multithreading mutex
1个回答
0
投票
@NateEldredge 我知道访问共享变量时线程应该同步。但由于

A_thread_ready

 只被 
A
 写入一次,并且更改涉及一个字节的一位,因此每当 
B
 读取 
A_thread_ready
 时,它都会得到 
0
1
 并且不应该有任何不确定性。

A_thread_ready

pthread_mutex_lock()
 返回后写入。我不明白当它设置为
1
但互斥量尚未锁定时会发生什么?

如有错误请指正。

© www.soinside.com 2019 - 2024. All rights reserved.