同步就是指同时起步,协调一致。不同的对象,对同步的理解方式也不尽相同。比如说,设备同步是指在两个设备之间规定一个共同的时间参考;数据库同步是指让两个或多个数据库内容保持一致,或者按照需要部分保持一致;文件同步是指让两个或多个文件夹中的文件保持一致。而在多线程中,同步是指协同、协助、互相配合,主要目的是协调步骤,按照预先定好的顺序依次运行。线程同步就是指,一个线程在发出某一功能调用时,在没有得到结果之前,该调用不返回,并且同时其它线程为保证数据一致性,不能调用该功能。如果没有同步机制,会产生“与时间有关的错误 time related”,为了避免这种数据混乱,线程之间必须要同步。通过同步就可以解决这种与时间有关的错误,避免数据混乱。实际上,线程之间、进程之间、信号之间都需要同步机制。也就是说,多个控制流共同操作一个共享资源的情况,都需要同步。数据混乱主要有三个原因:
这三点中,前两点都是无法更改的,因为资源共享是提高数据传递效率的最佳方法,而一旦资源共享,就势必会出现竞争,只要存在竞争,就可能会导致数据混乱。所以,解决方法只能从同步机制下手,在访问共享资源的时候使用互斥机制。
#include <pthread.h>
/*销毁一个锁*/
int pthread_mutex_destroy(pthread_mutex_t *mutex);
/*初始化一个锁*/
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
/*也可以初始化一个锁*/
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#include <pthread.h>
/*给共享资源加锁,如果共享资源已经加锁,则阻塞等待*/
int pthread_mutex_lock(pthread_mutex_t *mutex);
/*尝试加锁,如果共享资源已经加锁不会阻塞,会返回错误码和错误信息*/
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
/*初始化一个锁*/
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* th1(void* arg)
{
while(1)
{
/*上锁*/
pthread_mutex_lock(&mutex);
/*进入临界区,都要打屏,会竞争*/
printf("11111");
sleep(rand()%3);
printf("22222\n");
/*释放锁*/
pthread_mutex_unlock(&mutex); /*加锁一定要最小区域加锁,一旦离开共享资源区,立即释放锁*/
sleep(rand()%3);
}
}
void* th2(void* arg)
{
while(1)
{
pthread_mutex_lock(&mutex); /*若加锁失败,阻塞等待*/
printf("aaaaa");
sleep(rand()%3);
printf("bbbbb\n");
pthread_mutex_unlock(&mutex);
sleep(rand()%3);
}
}
int main(int argc, char* argv[])
{
pthread_t tid[2];
pthread_create(&tid[0], NULL, th1, NULL);
pthread_create(&tid[1], NULL, th2, NULL);
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
return 0;
}
死锁主要有两种情况
实际上,互斥量mutex只是建议锁,也就是说即使不加锁也能访问共享资源,并非操作系统强制只有加锁才能访问。