互斥锁
正如上面所说的,如果两个线程同时对一块内存进行读写或者对向同一个文件写数据,那么结果是难以设想的。正因为如此,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
例如int *a int *b 分别指向两块内存,上面的值分别初始化为(200, 100) 线程A执行这样的一个操作:将*a的值减少50,*b的值增加50.
线程B执行:打印出(a 跟 b 指向的内存的值的和)。
如果串行运行:A: *a -= 50; *b += 50; B: printf("%d\n", *a + *b);
如果并发执行,则有可能会出现一下调度:*a -= 50; printf("%d\n", *a + *b); *b += 50;
因此我们可以引入互斥量,在对共享数据读写时进行锁操作,实现对内存的访问以互斥的形式进行。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int
a = 200;
int
b = 100;
pthread_mutex_t lock;
void
* ThreadA(
void
* arg)
{
pthread_mutex_lock(&lock);
//锁
a -= 50;
sleep(5);
//执行到一半 使用sleep 放弃cpu调度
b += 50;
pthread_mutex_unlock(&lock);
}
void
* ThreadB(
void
* arg)
{
sleep(1);
//放弃CPU调度 目的先让A线程运行。
pthread_mutex_lock(&lock);
printf
(
"%d\n"
, a + b);
pthread_mutex_unlock(&lock);
}
int
main()
{
pthread_t tida, tidb;
pthread_mutex_init(&lock, NULL);
pthread_create(&tida, NULL, ThreadA, NULL);
pthread_create(&tidb, NULL, ThreadB, NULL);
pthread_join(tida, NULL);
pthread_join(tidb, NULL);
return
1;
}
|
以上输出为300 去掉锁操作 输出为250。