使用信号量解决互斥和同步
利用信号量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/*