其实就是利用信号量机制实现线程的同步和互斥,在实现代码之前先了解一下什么是信号量机制
信号量机制
简单说信号量其实就是一个变量,这个变量用于记录系统中某种资源的数量,用sem表示,初始时sem>=0。
P,V操作
P操作:即wait(),用于对一个资源的申请,当信号量>0时申请操作成功,后将信号量值做减一操作,若信号量<=0,会将申请资源的进程进行阻塞,等到需要申请的资源空闲后才会继续执行。
V操作:即post(),用于对一个资源的释放,后对信号量做加1操作。
所以先定义一个信号量,以及对信号量的初始化,这儿初始信号量为0,便于阻塞线程的运行
sem_t sem;
unsigned int value=0;
if(0!=sem_init(&sem,0,value)) //初始化信号量
{
perror("init failed!\n");
exit(-1);
}
先分别创建两个线程,一个线程负责执行n++操作,另一个线程执行打印n的值,使用pthread_creat函数创建线程。
pthread_t p1,p2;
if(0!= pthread_create(&p1,NULL,pthread1,NULL))
{
perror("pthread1 failed!\n");
exit(-1);
}
if(0!= pthread_create(&p2,NULL,pthread2,NULL))
{
perror("pthread2 failed!\n");
exit(-1);
}
其中pthread1和pthread2的函数实现分别如下
void* pthread1(void* arg)
{
while(1)
{
if(0!=sem_post(&sem))
{
perror("sem_wait1 failed!\n");
exit(-1);
}
printf("p1**********%d\n",n);
sleep(1);
}
pthread_exit(NULL);
}
void* pthread2(void* arg)
{
while(1)
{
if(0!=sem_wait(&sem))
{
perror("sem_pos2 failed!\n");
exit(-1);
}
n++;
sleep(1);
}
pthread_exit(NULL);
}
接下来进行分析,首先信号量初值为0,由于信号量在>0时进行wait操作才会为该线程分配资源,所以线程pthread2进行wait操作后被阻塞,所以不会抢占cpu,这时线程pthread1进行post操作,释放资源,信号量value的值为1,进行打印n值的操作,随后线程pthread2进行wait操作,此时资源已被线程pthread1释放,线程pthread抢占到资源便会进行n++操作,随后不断进行此循环,便完成题意。
全代码如下
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
int n=0;
pthread_t p1;
pthread_t p2;
sem_t sem;
void* pthread1(void* arg)
{
while(1)
{
if(0!=sem_post(&sem))
{
perror("sem_wait1 failed!\n");
exit(-1);
}
printf("p1**********%d\n",n);
sleep(1);
}
pthread_exit(NULL);
}
void* pthread2(void* arg)
{
while(1)
{
if(0!=sem_wait(&sem))
{
perror("sem_pos2 failed!\n");
exit(-1);
}
n++;
sleep(1);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
unsigned int value=0;
if(0!= pthread_create(&p1,NULL,pthread1,NULL))
{
perror("pthread1 failed!\n");
exit(-1);
}
if(0!= pthread_create(&p2,NULL,pthread2,NULL))
{
perror("pthread2 failed!\n");
exit(-1);
}
if(0!=sem_init(&sem,0,value)) //初始化信号量
{
perror("init failed!\n");
exit(-1);
}
pthread_join(p1,NULL);
pthread_join(p2,NULL);
return 0;
}