概述
(一)信号灯简介
(1)线程同步是指多个任务按照约定的先后顺序相互配合完成一件事情。
eg:生产者(P + )和消费者(V - )的需要约定执行操作的先后顺序:
比如制造生产汽车,在整车还未完全生产完成,消费者拿到的产品是有问题的。因此消费者必须得等待生产者把正常生产完成后,才能消费者正常的消费使用。
(2)1968年,Edsgar Dijkstra基于信号量的概念提出了一种同步机制:由信号量(灯)的值 通过PV操作来决定线程是继续运行还是阻塞等待。
(3)信号量代表某一类资源的统称,其值表示系统中该资源的数量。信号量是一个受保护的变量,只能通过三种操作来访问:
初始化:sem_init
P操作(申请资源):sem_wait 自动对信号数量 减1
V操作(释放资源):sem_post 自动对信号数量 加1
(二)Posix信号量
linux下遵循posix标准定义了两类信号量:
无名信号量(基于内存的信号量)
有名信号量
(三)semaphore库常用的信号量函数
头文件:#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);//初始化
int sem_wait(sem_t *sem);//P操作
int sem_post(sem_t *sem);//V操作
(1)sem:sem是要操作的信号量对象
(2)pshared:
0 表示线程间的信号量
1 表示进程间的信号量
(3 value:value就是信号量的个数。
(4)成功返回 0
失败返回 EOF
(四)注意事项
1)线程里面不可以写exit,否则整个进程都退出。
2)main函数退出,整个程序就退出,线程不存在。
3)线程的函数如果执行完毕,线程不存在,但是之前占用的资源还是存在的,因此也需要回收。
4) 不同的线程TID要区别开。
程序(一):利用两个信号量完成对共享内存的读和写
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <pthread.h>
4 #include <semaphore.h>
5 #include <string.h>
6
7 #define NUM 128
8
9 char sharemem[NUM];
10 sem_t sem_rd; //定义的两个读和写信号量
11 sem_t sem_wr;
12
13 void * read_pthread(void * arg);
14 void * write_pthread(void * arg);
15
16 int main(int argc, const char *argv[])
17 {
18 pthread_t read_tid;
19 pthread_t write_tid;
20
21 pthread_create(&read_tid, NULL, read_pthread, NULL);
22 pthread_create(&write_tid, NULL, write_pthread, NULL);
23
24 sem_init(&sem_rd, 0, 0);
25 sem_init(&sem_wr, 0, 1);
26
27
28 while(1)
29 {
30 sleep(1);
31 }
32 return 0;
33 }
34
35 void * write_pthread(void * arg)
36 {
37 char buf[20] = "";
38
39 pthread_detach(pthread_self());
40 while(1)
41 {
42 sem_wait(&sem_wr);
43 fgets(buf, 20, stdin);
44 memset(sharemem, 0, NUM);
45 memcpy(sharemem, buf, strlen(buf));//注意此时不能用sizeof(buf),因为始终sizeof是固定值,strlen才是得到字符串的长度。
46 sem_post(&sem_rd);
47 }
48 }
49
50 void * read_pthread(void * arg)
51 {
52 pthread_detach(pthread_self());
53 while(1)
54 {
55 sem_wait(&sem_rd);
56 printf("%sn", sharemem);
57 sem_post(&sem_wr);
58 }
59 }
程序(二):优化利用一个信号量进程读和写操作
或者在一个线程执行的前面加usleep(1000)延迟一下;
sem_init(&sem, 0, 0);
35 void * write_pthread(void * arg)
36 {
37 char buf[20] = "";
38
39 pthread_detach(pthread_self());
40 while(1)
41 {
43 fgets(buf, 20, stdin);
44 memset(sharemem, 0, NUM);
45 memcpy(sharemem, buf, strlen(buf));//注意此时不能用sizeof(buf),因为始终sizeof是固定值,strlen才是得到字符串的长度。
46 sem_post(&sem);
47 }
48 }
49
50 void * read_pthread(void * arg)
51 {
52 pthread_detach(pthread_self());
53 while(1)
54 {
55 sem_wait(&sem);
56 printf("%sn", sharemem);
57
58 }
59 }
最后
以上就是活泼海燕为你收集整理的线程间通信-同步信号量(灯)的全部内容,希望文章能够帮你解决线程间通信-同步信号量(灯)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复