linux 线程的同步 三 (内存信号量的使用)
- int sem_init(sem_t *sem, int pshared, unsigned int value);
- int sem_wait(sem_t *sem);
- int sem_post(sem_t *sem);
- int sem_destroy(sem_t *sem);
- #include <unistd.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- //线程函数
- void *thread_func(void *msg);
- sem_t sem;//信号量
- #define MSG_SIZE 512
- int main()
- {
- int res = -1;
- pthread_t thread;
- void *thread_result = NULL;
- char msg[MSG_SIZE];
- //初始化信号量,其初值为0
- res = sem_init(&sem, 0, 0);
- if(res == -1)
- {
- perror("semaphore intitialization failed\n");
- exit(EXIT_FAILURE);
- }
- //创建线程,并把msg作为线程函数的参数
- res = pthread_create(&thread, NULL, thread_func, msg);
- if(res != 0)
- {
- perror("pthread_create failed\n");
- exit(EXIT_FAILURE);
- }
- //输入信息,以输入end结束,由于fgets会把回车(\n)也读入,所以判断时就变成了“end\n”
- printf("Input some text. Enter 'end'to finish...\n");
- while(strcmp("end\n", msg) != 0)
- {
- fgets(msg, MSG_SIZE, stdin);
- //把信号量加1
- sem_post(&sem);
- }
- printf("Waiting for thread to finish...\n");
- //等待子线程结束
- res = pthread_join(thread, &thread_result);
- if(res != 0)
- {
- perror("pthread_join failed\n");
- exit(EXIT_FAILURE);
- }
- printf("Thread joined\n");
- //清理信号量
- sem_destroy(&sem);
- exit(EXIT_SUCCESS);
- }
- void* thread_func(void *msg)
- {
- //把信号量减1
- sem_wait(&sem);
- char *ptr = msg;
- while(strcmp("end\n", msg) != 0)
- {
- int i = 0;
- //把小写字母变成大写
- for(; ptr[i] != '\0'; ++i)
- {
- if(ptr[i] >= 'a' && ptr[i] <= 'z')
- {
- ptr[i] -= 'a' - 'A';
- }
- }
- printf("You input %d characters\n", i-1);
- printf("To Uppercase: %s\n", ptr);
- //把信号量减1
- sem_wait(&sem);
- }
- //退出线程
- pthread_exit(NULL);
- }

- printf("Input some text. Enter 'end'to finish...\n");
- while(strcmp("end\n", msg) != 0)
- {
- if(strncmp("TEST", msg, 4) == 0)
- {
- strcpy(msg, "copy_data\n");
- sem_post(&sem);
- }
- fgets(msg, MSG_SIZE, stdin);
- //把信号量加1
- sem_post(&sem);
- }

- #include <unistd.h>
- #include <pthread.h>
- #include <semaphore.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- //线程函数
- void *thread_func(void *msg);
- sem_t sem;//信号量
- sem_t sem_add;//增加的信号量
- #define MSG_SIZE 512
- int main()
- {
- int res = -1;
- pthread_t thread;
- void *thread_result = NULL;
- char msg[MSG_SIZE];
- //初始化信号量,初始值为0
- res = sem_init(&sem, 0, 0);
- if(res == -1)
- {
- perror("semaphore intitialization failed\n");
- exit(EXIT_FAILURE);
- }
- //初始化信号量,初始值为1
- res = sem_init(&sem_add, 0, 1);
- if(res == -1)
- {
- perror("semaphore intitialization failed\n");
- exit(EXIT_FAILURE);
- }
- //创建线程,并把msg作为线程函数的参数
- res = pthread_create(&thread, NULL, thread_func, msg);
- if(res != 0)
- {
- perror("pthread_create failed\n");
- exit(EXIT_FAILURE);
- }
- //输入信息,以输入end结束,由于fgets会把回车(\n)也读入,所以判断时就变成了“end\n”
- printf("Input some text. Enter 'end'to finish...\n");
- sem_wait(&sem_add);
- while(strcmp("end\n", msg) != 0)
- {
- if(strncmp("TEST", msg, 4) == 0)
- {
- strcpy(msg, "copy_data\n");
- sem_post(&sem);
- //把sem_add的值减1,即等待子线程处理完成
- sem_wait(&sem_add);
- }
- fgets(msg, MSG_SIZE, stdin);
- //把信号量加1
- sem_post(&sem);
- //把sem_add的值减1,即等待子线程处理完成
- sem_wait(&sem_add);
- }
- printf("Waiting for thread to finish...\n");
- //等待子线程结束
- res = pthread_join(thread, &thread_result);
- if(res != 0)
- {
- perror("pthread_join failed\n");
- exit(EXIT_FAILURE);
- }
- printf("Thread joined\n");
- //清理信号量
- sem_destroy(&sem);
- sem_destroy(&sem_add);
- exit(EXIT_SUCCESS);
- }
- void* thread_func(void *msg)
- {
- char *ptr = msg;
- //把信号量减1
- sem_wait(&sem);
- while(strcmp("end\n", msg) != 0)
- {
- int i = 0;
- //把小写字母变成大写
- for(; ptr[i] != '\0'; ++i)
- {
- if(ptr[i] >= 'a' && ptr[i] <= 'z')
- {
- ptr[i] -= 'a' - 'A';
- }
- }
- printf("You input %d characters\n", i-1);
- printf("To Uppercase: %s\n", ptr);
- //把信号量加1,表明子线程处理完成
- sem_post(&sem_add);
- //把信号量减1
- sem_wait(&sem);
- }
- sem_post(&sem_add);
- //退出线程
- pthread_exit(NULL);
- }
其运行结果如下:

linux 线程的同步 三 (内存信号量的使用)的更多相关文章
- Linux并发与同步专题 (3) 信号量
关键词:Semaphore.down()/up(). <Linux并发与同步专题 (1)原子操作和内存屏障> <Linux并发与同步专题 (2)spinlock> <Li ...
- linux 线程的同步 一 (互斥量和信号量)
互斥量(Mutex) 互斥量表现互斥现象的数据结构,也被当作二元信号灯.一个互斥基本上是一个多任务敏感的二元信号,它能用作同步多任务的行为,它常用作保护从中断来的临界段代码并且在共享同步使用的资源. ...
- linux线程间同步方式总结梳理
线程间一般无需特别的手段进行通信,由于线程间能够共享数据结构,也就是一个全局变量能够被两个线程同时使用.只是要注意的是线程间须要做好同步! 使用多线程的理由: 1. 一个是和进程相比,它是一种非常&q ...
- Linux线程间同步的几种方式
信号量 信号量强调的是线程(或进程)间的同步:"信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在sem_wait的时候,就阻塞 ...
- 线程间同步之 semaphore(信号量)
原文地址:http://www.cnblogs.com/yuqilin/archive/2011/10/16/2214429.html semaphore 可用于进程间同步也可用于同一个进程间的线程同 ...
- linux线程(二)内存释放
linux线程有两种模式joinable和unjoinable. joinable线程:系统会保存线程资源(栈.ID.退出状态等)直到线程退出并且被其他线程join. unjoinable线程:系统会 ...
- linux线程间同步方式汇总
抽空做了下linux所有线程间同步方式的汇总(原生的),包含以下几个: 1, mutex 2, condition variable 3, reader-writer lock 4, spin loc ...
- linux 线程的同步 二 (互斥锁和条件变量)
互斥锁和条件变量 为了允许在线程或进程之间共享数据,同步时必须的,互斥锁和条件变量是同步的基本组成部分. 1.互斥锁 互斥锁是用来保护临界区资源,实际上保护的是临界区中被操纵的数据,互斥锁通常用于保护 ...
- linux线程间同步(1)读写锁
读写锁比mutex有更高的适用性,能够多个线程同一时候占用读模式的读写锁.可是仅仅能一个线程占用写模式的读写锁. 1. 当读写锁是写加锁状态时,在这个锁被解锁之前,全部试图对这个锁加锁的线程都会被堵塞 ...
随机推荐
- 20145311 《Java程序设计》第九周学习总结
20145311 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 整合数据库 16.1JDBC 16.1.1JDBC简介 JDBC(Java DataBase Connec ...
- tomcat的安装和启动
下载apache-tomcat-8.5.5-src,我将其放在了/usr/local/tomcat目录下 要启动需要运行: /usr/local/tomcat/apache-tomcat-8.5.5- ...
- 同样的输入,为什么Objects.hash()方法返回的hash值每次不一样?
背景 开发过程中发现一个问题,项目中用Set保存AopMethod对象用于去重,但是发现即使往set中添加相同内容的对象,每次也能够添加成功. AopMethod类的部分代码如下: public cl ...
- 安全之路:Web渗透技术及实战案例解析(第2版)
安全之路:Web渗透技术及实战案例解析(第2版)
- Android -- service 服务的创建与使用,生命周期,电话监控器
1. 为什么使用service 应用程序 : 一组组件(activity service provider receiver)的集合. 一般情况 一个应用程序 会对应一个进程. 一般情况 关闭掉应用 ...
- jsapi微信扫一扫
微信公众号开发--微信JS-SDK扫一扫功能 首先请阅读微信JS-SDK说明文档,了解微信JS的相关说明. 根据官方的使用步骤,关键的有以下几步 绑定域名(很关键) 引入JS文件(很简单) 通过con ...
- sshpass使用
sshpass的使用方法 应用范围:可以在命令行直接使用密码来进行远程连接和远程拉取文件. 使用前提:对于未连接过的主机.而又不输入yes进行确认,需要进行sshd服务的优化: # vim /etc/ ...
- 解决ubuntu登陆失败,"Failed to start session"的问题
我是在虚拟机中安装了Ubuntu 14.04 系统,在Ubuntu 中执行 apt-get update 和 apt-get upgrade 命令后,然后重启系统. 但是,在重启成功后,在登 ...
- springboot 用mybatis-generator自动生成bean和dao
1.在pom.xml里添加maven插件 <plugin> <groupId>org.mybatis.generator</groupId> <artifac ...
- Kaggle比赛冠军经验分享:如何用 RNN 预测维基百科网络流量
Kaggle比赛冠军经验分享:如何用 RNN 预测维基百科网络流量 from:https://www.leiphone.com/news/201712/zbX22Ye5wD6CiwCJ.html 导语 ...