信号量进行同步(linux POSIX的实时扩展,用于线程)!
2015-08-27 15:38
537 查看
信号量提出背景:
程序中2线程共享全局变量时(一个是main函数顺序“线程”,一个是create线程),会导致“忙等待”时,线程之间
来回切换,非常笨拙且没有效率,由此荷兰计算机科学家Dijkstra提出了信号量的概念;
对信号量的一般特点:
1. 有2组,一组是posix的实时扩展,用于线程(本博的主要内容);另外一组为系统V信号量,用于进程同步;
2. 信号量是特殊的变量,可以被增加和减少,一般用最简单的信号量--二进制,另外一种是计数信号量,不在此讨论;
计数信号量不常用;
相关函数:
线程中使用的基本信号量函数有4个,
1.头文件:#include <semaphore.h>
2.原型:
int sem_init(sem_t *sem, int pshared, unsigned int value);
pshared 参数控制信号量的类型,为0,:表示这个信号量是当前的进程的局部信号量,否则,这个信号量可以在多个进程之间
共享;(该博只对不能在进程间共享的信号量感兴趣);
int sem_post(sem_t *sem);
int sem_wait(sem_t *sem);
1. sem_post 函数的作用是以原子操作的方式给信号量的值加1.(原子操作:P424有说明);
2. sem_wait函数以原子操作的方式将信号量的值减1,它会等待直到信号量有个非零值才会开始减操作,为0就等待;
3. 如果有2个wait等待信号量为非零值,只有一个等待线程开始对信号量减1,另外一个线程继续等待;
int sem_destroy(sem_t *sem);
与大多数linux函数一样,成功返回0。
例子:
去掉thread_function函数体内的第一个sem_wait(&bin_sem)会出现什么现象,删除第二个呢?初始设信号量为1又是怎么打印呢?
删除第一个的打印情况:
删除第二个sem_wait(&bin_sem)打印情况如下:(死循环)
初始设信号量为1又是怎么打印:
程序中2线程共享全局变量时(一个是main函数顺序“线程”,一个是create线程),会导致“忙等待”时,线程之间
来回切换,非常笨拙且没有效率,由此荷兰计算机科学家Dijkstra提出了信号量的概念;
对信号量的一般特点:
1. 有2组,一组是posix的实时扩展,用于线程(本博的主要内容);另外一组为系统V信号量,用于进程同步;
2. 信号量是特殊的变量,可以被增加和减少,一般用最简单的信号量--二进制,另外一种是计数信号量,不在此讨论;
计数信号量不常用;
相关函数:
线程中使用的基本信号量函数有4个,
1.头文件:#include <semaphore.h>
2.原型:
int sem_init(sem_t *sem, int pshared, unsigned int value);
pshared 参数控制信号量的类型,为0,:表示这个信号量是当前的进程的局部信号量,否则,这个信号量可以在多个进程之间
共享;(该博只对不能在进程间共享的信号量感兴趣);
int sem_post(sem_t *sem);
int sem_wait(sem_t *sem);
1. sem_post 函数的作用是以原子操作的方式给信号量的值加1.(原子操作:P424有说明);
2. sem_wait函数以原子操作的方式将信号量的值减1,它会等待直到信号量有个非零值才会开始减操作,为0就等待;
3. 如果有2个wait等待信号量为非零值,只有一个等待线程开始对信号量减1,另外一个线程继续等待;
int sem_destroy(sem_t *sem);
与大多数linux函数一样,成功返回0。
例子:
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# cat -n thread3.c 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <pthread.h> 6 #include <semaphore.h> 7 8 void *thread_function(void *arg); 9 sem_t bin_sem; 10 11 #define WORK_SIZE 1024 12 char work_area[WORK_SIZE]; 13 14 int main() { 15 int res; 16 pthread_t a_thread; 17 void *thread_result; 18 19 res = sem_init(&bin_sem, 0, 0); 20 if (res) { 21 perror("Semaphore initialization failed"); 22 exit(EXIT_FAILURE); 23 } 24 res = pthread_create(&a_thread, NULL, thread_function, NULL); 25 if (res) { 26 perror("Thread creation failed"); 27 exit(EXIT_FAILURE); 28 } 29 printf("Input some text. Enter 'end' to finish\n"); 30 while(memcmp("end", work_area, 3) != 0) { 31 fgets(work_area, WORK_SIZE, stdin); 32 sem_post(&bin_sem); 33 } 34 printf("\nWaiting for thread to finish...\n"); 35 res = pthread_join(a_thread, &thread_result); 36 if (res) { 37 perror("Thread join failed"); 38 exit(EXIT_FAILURE); 39 } 40 printf("Thread joined\n"); 41 sem_destroy(&bin_sem); 42 exit(EXIT_SUCCESS); 43 } 44 45 void *thread_function(void *arg) { 46 sem_wait(&bin_sem); 47 while(memcmp("end", work_area, 3) != 0) { 48 printf("You input %d characters\n", strlen(work_area)-1); 49 sem_wait(&bin_sem); 50 } 51 pthread_exit(NULL); 52 } root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3 Input some text. Enter 'end' to finish end Waiting for thread to finish... Thread joined root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3 Input some text. Enter 'end' to finish hello world You input 11 characters endget Waiting for thread to finish... Thread joined root@ubuntu:/mnt/hgfs/D/linux_program/ch12#
去掉thread_function函数体内的第一个sem_wait(&bin_sem)会出现什么现象,删除第二个呢?初始设信号量为1又是怎么打印呢?
删除第一个的打印情况:
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3 Input some text. Enter 'end' to finish You input -1 characters clear You input 5 characters end Waiting for thread to finish... Thread joined root@ubuntu:/mnt/hgfs/D/linux_program/ch12#
删除第二个sem_wait(&bin_sem)打印情况如下:(死循环)
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# gcc -D_REENTRANT -o thread3 thread3.c -lpthread root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3 Input some text. Enter 'end' to finish hello csdn You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters You input 10 characters ^[^AYou input 10 characters You input 10 characters You input 10 characters You input 10 characters ^C root@ubuntu:/mnt/hgfs/D/linux_program/ch12#
初始设信号量为1又是怎么打印:
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3 Input some text. Enter 'end' to finish You input -1 characters clear You input 5 characters c You input 1 characters hello csdn You input 10 characters end Waiting for thread to finish... Thread joined root@ubuntu:/mnt/hgfs/D/linux_program/ch12#
相关文章推荐
- linux用户管理及相关命令-8-25
- linux常用命令(6):rmdir命令
- Linux系统—— core 文件
- Linux进程间通过pipe通信
- linux系统——ld-linux.so.X查找和加载共享动态库的顺序
- Linux系统——提高编译速度的方法
- linux进程——后台运行的方法
- Install ffmpeg on CentOS (RHEL/Fedora)
- linux系统初始化——文件系统初始化步骤
- linux系统初始化——启动脚本是如何工作的
- linux系统初始化——sysinit文件写法详解
- linux系统初始化——inittab文件解析
- linux常用命令(5):rm命令
- linux系统初始化——busybox的inittab文件格式说明
- 基于Linux的嵌入式文件系统构建与设计
- Linux内核对于信号的实现机制和应用层的相关处理
- linux - 扫描技术与安全防范
- CentOS上 svn客户端的安装及应用
- linux 常见服务端口
- 树莓派常用Linux命令