线程并发引起的同步问题
线程以并发形式运行,当并发的线程间访问共享数据时,会发后争用现象,不进行同步控制的线程运行会造成不恰当的结果。
生产者消费者同步问题
生产者消费者是典型的同步问题,他们共享了一个缓冲池(全局变量数组),当缓冲池有空位时生产者线程向缓冲池中依次赋值,如果缓冲池满则等待。当缓冲池中有数据时消费者线程从中取走数据,如果缓冲池空则等待。
如何解决线程间访问共享变量的冲突问题
当多个线程访问同一个共享变量时,共享变量成为临界资源,它需要操作系统提供同步控制机制,以保证多个线程可以依序访问,当一个线程操作临界资源时其它线程不会中断其操作,因此对临界资源的操作是安全的。
需要使用到的头文件和方法
#include
int sem_init(sem_t * sem, int pshared, unsigned int value);//创建信号量变量,value是信号量的初值
int sem_destroy(sem_t *sem);//销毁信号量
int sem_post(sem_t * sem); //信号量值增加1,并激活处于等待状态的线程
int sem_wait(sem_t * sem); //信号量值减少1 为0时将调用该方法的线程被OS阻塞
代码实现
//stu001.c 生产者消费者同步控制,由学生完成缺失代码。 //主线程序启动生产者线程和消费者线程,全局变量初值为0 //生产者线程向全局变量进行10次赋值(代表生产),消费者线程从全局变量读取值,///并重新赋值0(代表消费了产品) #include#include #include #include void * producer(void * arg); void * consumer(void * arg); static sem_t sem_empty;//空位个数 static sem_t sem_full; //可用数据个数 static sem_t sem_mutex; //互斥量,用于控制两个线程互斥访问缓冲区 static int buffer[]={0,0,0};//共享的缓冲区 int main(int argc,char * argv[]) { pthread_t id_prod,id_consum; sem_init(&sem_empty,0,3); //初值为3,空位为3, sem_init(&sem_full,0,0); //初值为0,可用数据个数为0, sem_init(&sem_mutex,0,1); //初值为1,用于控制两个线程互斥访问缓冲区 pthread_create(&id_prod, NULL,producer,NULL);//创建生产者线程 pthread_create(&id_consum,NULL,consumer,NULL);//创建消费者线程 pthread_join(id_prod,NULL); //主线程等待生产者线程结束 pthread_join(id_consum,NULL);//主线程等待消费者线程结束 sem_destroy(&sem_empty); sem_destroy(&sem_full); sem_destroy(&sem_mutex); return 0; } void * producer(void * arg) { int i,pIndex=0; for(i=11;i<21;i++) { //请在begin end语句间补全程序语句实现生产者向缓冲区赋值操作 sem_wait(&sem_empty); sem_wait(&sem_mutex); buffer[pIndex]=i; pIndex=(pIndex+1)%3; sem_post(&sem_mutex); sem_post(&sem_full); } return NULL; } void * consumer(void *arg) { int i,cIndex=0; for(i=11;i<21;i++) { //请在begin end语句间补全程序语句实现扫描算法,算出总访问磁道数存入totaltracks变量 sem_wait(&sem_full); sem_wait(&sem_mutex); printf("%d,",buffer[cIndex]); cIndex=(cIndex+1)%3; sem_post(&sem_mutex); sem_post(&sem_empty); } return NULL; }



