进程之间的关系主要有两种,同步与互斥。所谓互斥,是指散步在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它 们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。所谓同步,是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的 某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。
显然,同步是一种更为复杂的互斥,而互斥是一种特殊的同步。
也就是说互斥是两个线程之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行,而同步也是不能同时运行,但他是必须要安照某种次序来运行相应的线程(也是一种互斥)!
总结:
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源
以下是线程的几种互斥方式:
1、 互斥量。
通过使用pthread的互斥接口保护数据,确保同一时间只有一个线程访问数据。互斥量从本质上讲是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。如下例所示,就是互斥量对共享数据的操作:
#include <stdio.h>
#include <pthread.h>
int value = 0;//共享变量
pthread_mutex_t mutex;//互斥变量
void *mythread1();
void *mythread2();
void *mythread1()
{
int retval;
int i =0 ;
for(i=0;i<5;i++)
{
retval = pthread_mutex_lock(&mutex);//上锁
value = value + 1;//对共享变量的操作
printf("int thrtead1:i=%d value = %d\n",i,value);
retval = pthread_mutex_unlock(&mutex);//解锁
usleep(2000);
}
pthread_exit((void *)0);
}
void *mythread2()
{
int retval;
int i =0 ;
for(i=0;i<5;i++)
{
retval = pthread_mutex_lock(&mutex);//上锁
value = value + 1;//对共享变量的操作
printf("int thrtead2:i=%d value = %d\n",i,value);
retval = pthread_mutex_unlock(&mutex);//解锁
usleep(3000);
}
pthread_exit((void *)0);
}
int main()
{
int retval;
pthread_t tid1 ,tid2;
retval = pthread_create(&tid1,NULL,mythread1,&value);//创建线程
if(retval< 0)
{
printf("create thread1 error\n");
}
retval = pthread_create(&tid2,NULL,mythread2,&value);//创建线程
if(retval< 0)
{
printf("create thread2 error\n");
}
pthread_mutex_destroy(&mutex); //销毁互斥锁
pthread_join(tid1,NULL);//等待线程mythread1结束
pthread_join(tid2,NULL);//等待线程mythread1结束
return 0;
}
2、信号量
该信号量是Posix提供的基于内存的信号量,它们由应用程序分配信号量的内存空间。如下例所示,就是信号量对共享数据的操作:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
int value = 0;//共享变量
sem_t sem1,sem2;
void *mythread1();
void *mythread2();
void *mythread1()
{
int retval;
int i =0 ;
for(i=0;i<5;i++)
{
retval = sem_wait(&sem1);//上锁
value = value + 1;//对共享变量的操作
printf("int thrtead1:i=%d value = %d\n",i,value);
retval = sem_post(&sem1);//解锁
usleep(2000);
}
pthread_exit((void *)0);
}
void *mythread2()
{
int retval;
int i =0 ;
for(i=0;i<5;i++)
{
retval = sem_wait(&sem1);//上锁
value = value + 1;//对共享变量的操作
printf("int thrtead2:i=%d value = %d\n",i,value);
retval = sem_post(&sem1);//解锁
usleep(5000);
}
pthread_exit((void *)0);
}
int main()
{
int retval;
pthread_t tid1 ,tid2;
retval = sem_init(&sem1,0,1);
retval = pthread_create(&tid1,NULL,mythread1,&value);//创建线程
if(retval< 0)
{
printf("create thread1 error\n");
}
retval = pthread_create(&tid2,NULL,mythread2,&value);//创建线程
if(retval< 0)
{
printf("create thread2 error\n");
}
pthread_join(tid1,NULL);//等待线程mythread1结束
pthread_join(tid2,NULL);//等待线程mythread1结束
sem_destroy(&sem1);
return 0;
}