使用信号量解决互斥和同步

使用信号量解决互斥和同步

利用信号量sem_t解决互斥和同步问题。

互斥

以典型的临界资源竞争为例,控制临界区。

同步

以典型的生产者消费者模型为例。

Tips

注意有信号量控制与无信号量控制的差异。

示例1:互斥

互斥代码

#include <stdio.h>
#include <unistd.h>

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

int switch_concurrency_control = 1;

sem_t sem; //信号量
 
void printer(char *str)
{
	if (switch_concurrency_control)
		sem_wait(&sem);//减一
	
	while(*str)
	{
		putchar(*str);	
		fflush(stdout);
		str++;
		sleep(1);
	}
	printf("\n");
	
	if (switch_concurrency_control)
		sem_post(&sem);//加一
}
 
void *thread_fun1(void *arg)
{
	char *str1 = "hello";
	printer(str1);
}
 
void *thread_fun2(void *arg)
{
	char *str2 = "world";
	printer(str2);
}
 
int main(void)
{
	char input;
	printf("Do you want to use concurrency control? Y or N :");
	scanf("%c",&input);
	if (input == 'Y' || input == 'y'  )
		switch_concurrency_control = 1;
	else
		switch_concurrency_control = 0;
		
		
	pthread_t tid1, tid2;
	
	sem_init(&sem, 0, 1); //初始化信号量,初始值为 1
	
	//创建 2 个线程
	pthread_create(&tid1, NULL, thread_fun1, NULL);
	pthread_create(&tid2, NULL, thread_fun2, NULL);
	
	//等待线程结束,回收其资源
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL); 
	
	sem_destroy(&sem); //销毁信号量
	
	return 0;
}

互斥结果:采用信号量控制

[tj@tj bin]$ ./mutex_test
Do you want to use concurrency control? Y or N :y
hello
world
[tj@tj bin]$ 

互斥结果:不采用信号量控制

[tj@tj bin]$ ./mutex_test
Do you want to use concurrency control? Y or N :n
hweolrllod

[tj@tj bin]$ 

示例2:同步

同步代码

#include <stdio.h>
#include <unistd.h>

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

int switch_concurrency_control = 1;

sem_t sem_empty,sem_full;   //定义两个信号量

char ch = 'a';
 
void *pthread_producer(void *arg)  //此线程改变字符ch的值
{
	while(1)
	{
		if (switch_concurrency_control)
			sem_wait(&sem_empty);
			
		ch++;
		sleep(1);
		
		if (switch_concurrency_control)
			sem_post(&sem_full);
	}
}
 
void *pthread_consumer(void *arg)  //此线程打印ch的值
{
	while(1)
	{
		if (switch_concurrency_control)
			sem_wait(&sem_full);
			
		printf("%c",ch);
		fflush(stdout);
		
		if (switch_concurrency_control)
			sem_post(&sem_empty);
	}
}
 
int main(int argc, char *argv[])
{
	char input;
	printf("Do you want to use concurrency control? Y or N :");
	scanf("%c",&input);
	if (input == 'Y' || input == 'y' )
		switch_concurrency_control = 1;
	else
		switch_concurrency_control = 0;
	
	
	pthread_t tid1,tid2;
	sem_init(&sem_empty, 0, 0);   //初始化信号量
	sem_init(&sem_full, 0, 1);
	
	pthread_create(&tid1, NULL, pthread_producer, NULL);
	pthread_create(&tid2, NULL, pthread_consumer, NULL);
	
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	
	return 0;
}

同步结果:采用信号量控制

[tj@tj bin]$ ./sync_test
Do you want to use concurrency control? Y or N :y
abcdefghijklmnopqrstuvwxyz{|}~^Z
[1]+  已停止               ./sync_test
[tj@tj bin]$ 

同步结果:不采用信号量控制

[tj@tj bin]$ ./sync_test
Do you want to use concurrency control? Y or N :n
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccdddddddddd
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddee
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee^Zeeeeeeeeeeeeeeeeeeeeeeee
[2]+  已停止               ./sync_test
[tj@tj bin]$ 

自动编译

shell编译方式

# clean
echo "************"
echo "clean project"
rm ./obj/*.o
rm ./bin/*
echo "clean complete"
echo "************"
echo ""
# compile link
echo "************************"
echo "gcc start"
gcc mutex_test.c -pthread -o ./bin/mutex_test
gcc sync_test.c -pthread -o ./bin/sync_test
echo "gcc complete"
echo "************************"

makefile编译方式

.PHONY: all
all: ./bin/mutex_test ./bin/sync_test

./bin/mutex_test: mutex_test.c
	gcc mutex_test.c -pthread -o ./bin/mutex_test
./bin/sync_test: sync_test.c
	gcc sync_test.c -pthread -o ./bin/sync_test
	
.PHONY: clean
clean:
	rm ./obj/*.o
	rm ./bin/*
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值