互斥锁在解锁之前是否会阻止访问?

假设此C代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <unistd.h>

pthread_mutex_t lock;  
int a = 0;

void *myThreadFun(void *vargp) 
{ 
   pthread_mutex_lock(&lock); 
   a = 5;
   while (1) sleep(1);
   pthread_mutex_unlock(&lock);
   return NULL; 
} 

int main() 
{
   pthread_mutex_init(&lock,NULL);
   pthread_t thread_id; 
   pthread_create(&thread_id,NULL,myThreadFun,NULL);
   while (1){
    a = 6;
    sleep(1); 
    printf("%d\n",a);
   }       
   pthread_join(thread_id,NULL); 
}

第一个输出为5,但随后的打印均为6。那个怎么样? myThreadFun创建一个锁并进入无限循环,永远不会解锁,那么main如何覆盖a

lock之间的任何内容都将受到保护?也就是说,如果我有更多myThreadFun中需要保护的变量,我只是将它们放在同一个锁之间?

锁是否会阻止访问直到被解锁,或者仅在完成自己的读/写操作后才阻止访问?即防止部分读写?

dgdfhdshdsh 回答:互斥锁在解锁之前是否会阻止访问?

myThreadFun创建一个锁并进入无限循环,永远不会解锁

是的,但是那个锁是用来做什么的呢?没有。除线程外,没有其他人会尊重锁。 main程序在不请求任何锁定的情况下访问变量。该程序对锁应该保护a变量这一事实一无所知。它可以真正用于任何事情。鉴于所有线程都在关键区域的开始处进行锁定,并在结束时进行解锁,因此锁只能防止多个线程同时执行这些关键区域。

如果要使其正常工作,则必须正确使用锁,并在与变量交互的代码的每个部分锁/释放锁。诸如此类(在main中):

while (1) {
    pthread_mutex_lock(&lock);
    a = 6;
    sleep(1);
    printf("%d\n",a);
    pthread_mutex_unlock(&lock);
}

锁是否会阻止访问直到被解锁,或者仅在完成自己的读/写操作后才阻止访问?即防止部分读写?

锁对读/写,代码或变量一无所知。锁只是具有两种状态的对象:锁定或解锁。如果其状态为解锁,则可以将其锁定。如果其状态为锁定,则只有在发生解锁时才能锁定它(并且请求锁定会使线程等待直到锁定被解锁)。

这仍然会打印6.我希望它打印5.我想将a锁定在一个线程中,以便其他任何线程都无法触摸它。

这是一个不同的问题。在这里您需要做的是确保正在启动的线程在主线程之前可以访问a变量 。如果要获得此结果,则需要将两者同步。换句话说,您希望main程序等待,直到线程将变量锁定。

这可以通过不同的方式来实现。这是一个使用信号量的工作示例(有关更多信息,请参见man sem_overview)。 注意,尽管看起来可以使用另一个互斥锁而不是信号量实现以下目的,但事实并非如此。互斥锁和信号量之间的主要区别在于,互斥锁只能由锁定它的同一线程解锁,而信号量则可以由不同的线程自由锁定或解锁。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>

sem_t sem_main;
pthread_mutex_t lock_var_a;
int a = 0;

void *myThreadFun(void *vargp)
{
    pthread_mutex_lock(&lock_var_a);

    // Signal main that I acquired the lock.
    sem_post(&sem_main);

    a = 5;
    while (1) {
        printf("Thread: a = %d\n",a);
        sleep(1);
    }

    pthread_mutex_unlock(&lock_var_a);

    return NULL;
}

int main()
{
    sem_init(&sem_main,0);
    pthread_mutex_init(&lock_var_a,NULL);

    pthread_t thread_id;
    pthread_create(&thread_id,NULL,myThreadFun,NULL);

    // Wait for thread to acquire the lock.
    sem_wait(&sem_main);

    while (1){
        pthread_mutex_lock(&lock_var_a);

        // This code will never be executed.
        a = 6;
        printf("Main: a = %d\n",a);
        sleep(1);

        pthread_mutex_unlock(&lock_var_a);
    }

    pthread_join(thread_id,NULL);
}

在上面的示例程序main中,线程将等待线程获取锁后才能继续。结果输出将是:

Thread: a = 5
Thread: a = 5
Thread: a = 5
...
,

如果希望某个变量只能在特定线程中访问 ,请在线程函数内 声明该变量:

void *myThreadFun(void *unused) 
{ 
   int a = 5;
   while (1) sleep(1);
   return 0;
}

现在main根本无法解决,并且不需要锁定。

本文链接:https://www.f2er.com/2588830.html

大家都在问