现在的位置: 首页 > 综合 > 正文

线程初步(2)信号量和死锁

2017年06月18日 ⁄ 综合 ⁄ 共 1630字 ⁄ 字号 评论关闭

信号量(semaphore)
信号量是一个计数器,用来控制访问临界资源的线程最大并行数量。当信号量的初始值为1时,效果等同于互斥量。
信号量不是最早的POSIX线程相关规范,因此信号量相关定义是在semaphore.h中。semaphore.h中定义的信号量,既可以用于线程,又可以用于进程。
信号量的使用步骤:
1、定义信号量 sem_t sem;
2、初始化信号量sem_init(&sem,0,计数初始值)
第二个参数为0,代表用于线程计数,其他值代表进程计数(进程计数目前Linux不支持)
3、获取信号量(减1)
sem_wait(&sem);
4、读写资源
5、释放信号量(加1)
sem_post(&sem);
6、删除信号量 sem_destroy(&sem);

死锁
mutex m1,m2;
init(m1);init(m2);
启动两个线程A、B;
A
 lock(m1)
         ...    <---运行到这个位置停止(时间片over)
         lock(m2) <--- 运行到此阻塞,等待B线程释放m2
...
 unlock(m2)
 unlock(m1)
B
      lock(m2)
...    <---运行到此,没有问题
 lock(m1)  <---阻塞,等待A线程释放m1
...    
 unlock(m1)
unlock(m2)
多线程编程时,必须避免死锁 --- 线程之间互相锁定叫死锁。避免死锁的经验:

顺序上锁,反向解锁,不要回调。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

char* data[5];//数组,存储名字
int size = 0;//当前人数,数组下标
sem_t sem;
//pthread_mutex_t lock;//1
//=PTHREAD_MUTEX_INITIALIZER;
void* task(void* p){
	//pthread_mutex_lock(&lock);//3
	sem_wait(&sem);
	data[size] = (char*)p;//4
	sleep(1);
	size++;
	sem_post(&sem);
	//pthread_mutex_unlock(&lock);//5
}

int main(){
	data[size] = "zhangfei";
	size++;
	pthread_t id1,id2;
	sem_init(&sem,0,1);
	pthread_create(&id1,0,task,"guanyu");
	pthread_create(&id2,0,task,"zhaoyun");
	pthread_join(id1,0);
	pthread_join(id2,0);
	//pthread_mutex_destroy(&lock);//5
	sem_destroy(&sem);
	int i;
	for (i = 0;i < size;i++){
		printf("%s\n",data[i]);
	}
}

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>

//模拟访问某资源的最大连接数控制
sem_t sem;
void* task(void* p){
	int i = (int)p;
	printf("第%d个线程开始运行\n",i);
	sem_wait(&sem);//计算减1,如果计算已经为0,阻塞等待
	printf("第%d线程连接成功\n",i);
	srand(time(0));
	int res = rand() % 10;
	sleep(res);
	printf("第%d个线程连接结束,释放资源\n",i);
	sem_post(&sem);
}
int main(){
	sem_init(&sem,0,10);//最多同时连接10个
	int i;
	for (i = 1;i < 21;i++){
		pthread_t id;
		pthread_create(&id,0,task,(void*)i);
	}
	while(1);
}

抱歉!评论已关闭.