linux多线程编程-信号量
信号量机制
锁机制使用是有限制的,锁只有两种状态,即加锁和解锁,对于互斥的访问一个全局变量,这样的方式还可以对付,但是要是对于其他的临界资源,比如说多台打印机等,这种方式显然不行了。
信号量机制在操作系统里面学习的比较熟悉了,信号量是一个整数计数器,其数值表示空闲临界资源的数量。
当有进程释放资源时,信号量增加,表示可用资源数增加;当有进程申请到资源时,信号量减少,表示可用资源数减少。这个时候可以把锁机制认为是0-1信号量。
关于信号量机制的函数 初始化信号量
int sem_init(sem_t * sem, int pshared, unsigned int value);
- 成功返回0,失败返回-1;
- 参数sem:表示指向信号结构的指针。
- 参数pshared:不是0 的时候该信号量在进程间共享,否则只能在当前进程的所有线程间共享。
- 参数value:信号量的初始值。
int sem_wait(sem_t *sem); 信号量减一操作,有线程申请资源
- 成功返回0,否则返回-1
- 参数sem:指向一个信号量的指针
int sem_post(sem_t *sem);信号量加一操作,有线程释放资源
- 成功返回0,否则返回-1
- 参数sem:指向一个信号量指针
int sem_destroy(sem_t *sem); 销毁信号量
- 成功返回0,否则返回-1
- 参数sem:指向一个信号量的指针。
信号量来解决多线程的同步问题,程序代码如下
#include
#include
#include
#include
#include
#include
void* ticketport1(void*);
void* ticketport2(void*);
int tickets=100;
sem_t mutex,full; //定义两个信号量
int main()
{
int ret;
pthread_t id1,id2;
ret=sem_init(&mutex,0,1); //初始化mutex信号量为1
ret+=sem_init(&full,0,0); //初始化full信号量为0
if(ret!=0)
{
perror("sem_init");
}
ret=pthread_create(&id1,NULL,ticketport1,NULL);
if(ret<0)
{
perror("creat thread1:");
exit(-1);
}
ret=pthread_create(&id2,NULL,ticketport2,NULL);
if(ret<0)
{
perror("creat thread2:");
exit(-1);
}
pthread_join(id1,NULL);
pthread_join(id2,NULL);
return 0;
}
void* ticketport1(void* arg)
{
while(1)
{
sem_wait(&mutex); //mutex信号量进行P操作
if(tickets>0)
{
usleep(1000);
printf("thread1 sell ticket: %d",tickets--);
sem_post(&full); //full信号量进行V操作
}
else
{
sem_post(&full); //full信号量进行V操作
break;
}
}
return (void*)0;
}
void* ticketport2(void* arg)
{
while(1)
{
sem_wait(&full); //full信号量进行P操作
if(tickets>0)
{
usleep(1000);
printf("thread2 sell ticket: %d",tickets--);
sem_post(&mutex); //mutex信号量进行V操作
}
else
{
sem_post(&mutex); //mutex信号量进行V操作
break;
}
}
return (void*)0;
}
上面的sem_init函数用来初始化两个信号量的初始化值,这里一个设为1,一个设为0,sem_wait类似于P操作,让信号量减1,如果小于结果小 于0,线程阻塞,否则线程继续执行,sem_post类似于V操作,提升信号量的值,加1,通过这两个信号量之间的互相“救对方”,就可以实现这两个线程 的同步执行
经典的生产者消费者问题,只有当生产者把资源放入存储区,消费者才能取得
#include
#include
#include
#include
#define MAXSIZE 10
int stack[MAXSIZE];
int size =0;
sem_t sem;
void privide_data(void)
{
int i;
for(i =0;i
{
stack[i] = i;
sem_post(&sem);
}
}
void handle_data(void)
{
int i;
while((i = size ++)
{
sem_wait(&sem);
printf("cross : %d X %d = %d ",stack[i],stack[i],stack[i] * stack[i]);
sleep(1);
}
}
int main()
{
pthread_t privider,handler;
sem_init(&sem,0,0);
pthread_create(&privider,NULL,(void *)&privide_data,NULL);
pthread_create(&handler,NULL,(void *)&handle_data,NULL);
pthread_join(privider,NULL);
pthread_join(handler,NULL);
sem_destroy(&sem);
return 0;
}