linux 中信号量 和 互斥量的 说明

<span style="font-size:18px;">#include<stdlib.h>  </span>
#include<stdio.h>  
#include<unistd.h>  
#include<pthread.h>  
typedef struct ct_sum  
{ int sum;  
  pthread_mutex_t lock;  
}ct_sum;  
void * add1(void * cnt)  
{       
     
    pthread_mutex_lock(&(((ct_sum*)cnt)->lock));  
    int i;  
        for( i=0;i<50;i++)  
        {(*(ct_sum*)cnt).sum+=i;  
          
        }  
    pthread_mutex_unlock(&(((ct_sum*)cnt)->lock));  
    pthread_exit(NULL);  
    return 0;  
}  
void * add2(void *cnt)  
{       
    int i;  
    cnt= (ct_sum*)cnt;  
    pthread_mutex_lock(&(((ct_sum*)cnt)->lock));  
    for( i=50;i<101;i++)  
    {    (*(ct_sum*)cnt).sum+=i;  
          
    }  
    pthread_mutex_unlock(&(((ct_sum*)cnt)->lock));  
    pthread_exit(NULL);  
    return 0;  
}  
  
  
int main(void)  
{ int i;  
  pthread_t ptid1,ptid2;  
  int sum=0;  
  ct_sum cnt;  
  pthread_mutex_init(&(cnt.lock),NULL);  
  cnt.sum=0;  
  
  pthread_create(&ptid1,NULL,add1,&cnt);  
pthread_create(&ptid2,NULL,add2,&cnt);  
   
 pthread_mutex_lock(&(cnt.lock));  
 printf("sum %d\n",cnt.sum);  
 pthread_mutex_unlock(&(cnt.lock));  
  
 pthread_join(ptid1,NULL);  
 pthread_join(ptid2,NULL);  
  pthread_mutex_destroy(&(cnt.lock));  
  return 0;  
}
<span style="font-size:18px;">如上面  在多个线程中 为了 不发生冲突  或者说  为了有个先后顺序 一旦 上锁 我们认为 其他线程 就阻塞了
在多个线程中如果 同时并发 若同时对一个对象访问 会出现不可预知的情况,如果加上 互斥锁 一次只有一个线程申请到执行,只有互斥锁释放后,其他线程才能执行
</span>



Linux下关于信号量结构体表示为:sem_t

      操作结构体的函数:

      初始化函数: sem_init(sem_t * __sem,int __pshared,unsigned int __value);

      触发信号量值:sem_post(sem_t * __sem);

      等待信号量触发:

      通常有:

      一直等待:sem_wait(sem_t * __sem);  

      测试__sem是否触发:sem_trywait(sem_t * __sem); 

      等待超时:sem_timedwait(sem_t * __restrict __sem, __ const struct timespec * __restrict __abstime);

      释放销毁信号量:

      sem _destroy(sem_t * __sem);


sem_wait(sem_t * __sem);  作用类似于把 信量的值减一 而  sem_post(sem_t * __sem);是将信号量的值加一


对于初始值为 1的 信号量  也可以作为 信号锁使用 我们称之为  用于互斥的信号量



#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>  
pthread_mutex_t mutex;

pthread_t id1;
pthread_t id2;
pthread_t id3;

sem_t sem1;
sem_t sem2;
sem_t sem3;


void* msg(void *arg)
{
	int i=0;
	pthread_mutex_lock(&mutex);
	sem_wait(&sem1);
	for(i=0;i<3;i++)
	{
		printf("  %d\n",i);
		sleep(1);
	}
	pthread_mutex_unlock(&mutex);
	sem_post(&sem1);
}
void * gff(void *arg)
{
	
	sleep(10);
	sem_wait(&sem1);
	printf("gff_test \n");
	
}
int main(int argc,char **argv)
{
	sem_init(&sem1,0,1);
	sem_init(&sem2,0,1);
	sem_init(&sem3,0,1);
	pthread_mutex_init(&mutex,NULL);
	pthread_create(&id1,NULL,msg,NULL);
	pthread_create(&id2,NULL,msg,NULL);
	pthread_create(&id3,NULL,gff,NULL);
	pthread_join(id1,NULL);
	pthread_join(id2,NULL);
	pthread_join(id3,NULL);
	pthread_mutex_destroy(&mutex);
	return 0;	

}
结果为:
  0
  1
  2
  0
  1
  2
gff_test

一共三个进程 msg 申请互斥锁后 其他两个 线程 阻塞,


下面经过 修改后 信号量 可实现 互斥的作用   或者 也可称为  互锁

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>
pthread_mutex_t mutex;

pthread_t id1;
pthread_t id2;
pthread_t id3;

sem_t sem1;
sem_t sem2;
sem_t sem3;

int i=0;
void* msg(void *arg)
{
	
	//pthread_mutex_lock(&mutex);
	sem_wait(&sem1);
	printf("msg get sem1\n");
	sleep(1);
	sem_wait(&sem2);
	for(i=0;i<3;i++)
	{
		printf("  %d\n",i);
		sleep(1);
	}
	//pthread_mutex_unlock(&mutex);
	sem_post(&sem1);
	sem_post(&sem2);
}
void * gff(void *arg)
{
	sem_wait(&sem2);
	printf("gff get sem2\n");
	sleep(1);
	sem_wait(&sem1);
	printf("gff_test \n");
	sem_post(&sem1);
	sem_post(&sem2);
	
}
int main(int argc,char **argv)
{
	sem_init(&sem1,0,1);
	sem_init(&sem2,0,1);
	sem_init(&sem3,0,1);
	pthread_mutex_init(&mutex,NULL);
	pthread_create(&id1,NULL,msg,NULL);
	//pthread_create(&id2,NULL,msg,NULL);
	pthread_create(&id3,NULL,gff,NULL);
	pthread_join(id1,NULL);
	//pthread_join(id2,NULL);
	pthread_join(id3,NULL);
	pthread_mutex_destroy(&mutex);
	return 0;	

}
结果
msg get sem1
gff get sem2


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值