C语言创建线程以及使用锁进行读写分离
线程的使用
1.线程的创建
线程的相关操作放在<pthread.h>中。
1.1我们定义一个线程,首先要进行定义一个函数,类似我们创建一个a线程
void *thread_a(void *in){
printf("Im thread_a\n");
pthread_exit((void*)0);
}
1.2.创建一个线程
pthread_t a;//声明
pthread_create(&a,NULL,thread_a,(void*)0);//创建线程
1.3.创建3个线程并且打印(如果你打印1000个,并且睡一秒,会发现,这个进程实际上运行是无序的)
#include <stdio.h>
#include <pthread.h>
void *thread_a(void *in){
printf("Im thread_a\n");
pthread_exit((void*)0);
}
void *thread_b(void *in){
printf("Im thread_b\n");
pthread_exit((void*)0);
}
void *thread_c(void *in){
printf("Im thread_c\n");
pthread_exit((void*)0);
}
int main(){
pthread_t a,b,c;
int val;
/**create thread a,b,c*/
pthread_create(&a,NULL,thread_a,(void*)0);
pthread_create(&b,NULL,thread_b,(void*)0);
pthread_create(&c,NULL,thread_c,(void*)0);
/**main thread waits for termination of a,b,c*/
pthread_join(a,(void**)0);
pthread_join(b,(void**)0);
pthread_join(c,(void**)0);
printf("Main thread is over\n");
return 0;
}
3.如果我们希望线程进行打印顺序为c,b,a,那么我们可以定义一个信号。
线程a等待线程2的信号,线程2等待线程3的信号
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>//sem_wait sem_init这些方法全在里面
sem_t sem1;
sem_t sem2;
void *thread_a(void *in){
sem_wait(&sem1);/*wait for sem1*/
printf("Im thread_a\n");
pthread_exit((void*)0);
}
void *thread_b(void *in){
sem_wait(&sem2);/*wait for sem2*/
printf("Im thread_b\n");
sem_post(&sem1);/*increase sem1 by 1,make thread_a run*/
pthread_exit((void*)0);
}
void *thread_c(void *in){
printf("Im thread_c\n");
sem_post(&sem2);/*increase sem2 by 1,make thread_b run*/
pthread_exit((void*)0);
}
int main(){
pthread_t a,b,c;
int val;
/**init sem1 sem2 to 0,any thread waits for it will be blocked*/
sem_init(&sem1,0,0);
sem_init(&sem2,0,0);
/**create thread a,b,c*/
pthread_create(&a,NULL,thread_a,(void*)0);
pthread_create(&b,NULL,thread_b,(void*)0);
pthread_create(&c,NULL,thread_c,(void*)0);
/**main thread waits for termination of a,b,c*/
pthread_join(a,(void**)0);
pthread_join(b,(void**)0);
pthread_join(c,(void**)0);
printf("Main thread is over\n");
/*destroy sem1,sem2*/
sem_destroy(&sem1);
sem_destroy(&sem2);
return 0;
}
2.锁的创建和使用
2.1.mutex互斥锁的创建
互斥锁的内容:我们要想创建一个互斥锁,首先是对这个mutex进行初始化操作。
互斥锁的头文件在<pthread.h>中。
pthread_mutex_t mutex;//声明一个锁
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
//加锁和解锁操作
pthread_mutex_destory(&mutex);//销毁锁的操作
2.2.编写一个读写(线程分离)的程序,读一个空串,然后写进另一个数组里面
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex;
char buf[80],buf1[80];
int n,buf_has_item=0;
void writer_function(void){
while(1){
pthread_mutex_lock(&mutex);
if(buf_has_item==0){
printf("等待从键盘读一个非空串:\n");
if((n=read(0,buf,sizeof(buf)))>0)
buf_has_item=1;
printf("A thread write:%s\n",buf);
}
pthread_mutex_unlock(&mutex);
}
}
void reader_function(void){
while(1){
pthread_mutex_lock(&mutex);
if(buf_has_item==1){
strcpy(buf1,buf);
buf_has_item=0;
printf("A thread read:%s\n",buf1);
}
pthread_mutex_unlock(&mutex);
}
}
void *thread_reader(void *in){
reader_function();
pthread_exit((void**)0);
}
int main(){
pthread_t reader,writer;pthread_t ptr;
pthread_mutex_init(&mutex,NULL);
pthread_create(&ptr,NULL,thread_reader,(void*)0);//创建一个线程
writer_function();
pthread_join(ptr,(void**)0);
return 0;
}
C语言创建线程以及使用锁进行读写分离的更多相关文章
- CreateThread创建线程 互斥量锁
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD:线程安全相关的属性,常置为NULL SIZE_T dwStackS ...
- UNIX网络编程卷1 server程序设计范式7 预先创建线程,以相互排斥锁上锁方式保护accept
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.预先创建一个线程池.并让每一个线程各自调用 accept 2.用相互排斥锁代替让每一个线 ...
- -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中
本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait( ...
- 如何使用双重检查锁定在 Java 中创建线程安全的单例?
这个 Java 问题也常被问: 什么是线程安全的单例,你怎么创建它.好吧,在Java 5之前的版本, 使用双重检查锁定创建单例 Singleton 时,如果多个线程试图同时创建 Singleton 实 ...
- JVM学习记录-线程安全与锁优化(一)
前言 线程:程序流执行的最小单元.线程是比进程更轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和执行调度分开,各个线程既可以共享进程资源(内存地址.文件I/O等),又可以独立调度(线程是C ...
- 02 如何创建线程 线程并发与synchornized
所有程序运行结果 请自行得出 创建线程方式一:继承Thread类 步骤: 1,定义一个类继承Thread类. 2,覆盖Thread类中的run方法. 3,直接创建Thread的子类对象创建线程. 4, ...
- UI:多线程 、用GCD创建线程
什么是应用(程序):就是我们编写的代码编译后生成的app文件 进程:凡是一个运行的程序都可以看作为一个进程,如打开的多个 word,就可以认为是一个进程的多个线程. 线程:至少有一个线程就是主线程,网 ...
- 偏向锁,偏向线程id ,自旋锁
理解锁的基础知识 如果想要透彻的理解Java锁的来龙去脉,需要先了解以下基础知识. 基础知识之一:锁的类型 锁从宏观上分类,分为悲观锁与乐观锁. 乐观锁 乐观锁是一种乐观思想,即认为读多写少,遇到并发 ...
- C语言实现线程池功能
1. 线程池基本原理 2. 线程池C语言实现 2.1 线程池的数据结构 #include <stdio.h> #include <pthread.h> #include < ...
随机推荐
- opengl球形网格生成
效果如图 准备第三方库 glew.freeglut.glm 代码包括主程序源文件mainApp.cpp.顶点着色器shader.vs.片元着色器shader.fs mainApp.cpp如下 #i ...
- 二分类Logistic回归模型
Logistic回归属于概率型的非线性回归,分为二分类和多分类的回归模型.这里只讲二分类. 对于二分类的Logistic回归,因变量y只有“是.否”两个取值,记为1和0.这种值为0/1的二值品质型变量 ...
- python 3 获取本机公网ip的几种方法
参考博客:https://blog.csdn.net/conquerwave/article/details/77666226 from urllib.request import urlopen f ...
- 最新 快乐阳光java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.快乐阳光等10家互联网公司的校招Offer,因为某些自身原因最终选择了快乐阳光.6.7月主要是做系统复习.项目复盘.Leet ...
- git 服务端安装
服务器端创建 git 用户,用来管理 Git 服务,并为 git 用户设置密码 [root@localhost home]# id git id: git:无此用户 [root@localhost h ...
- mysql导入数据报错:Incorrect datetime value
incorrect datetime value 报错信息如下图: 意思很明显是说,'0000-00-00 00:00:00'不是一个有效的日期类型的值 解决办法: sql_mode 中删除 NO_Z ...
- Nginx之rewrite四种flag
利用nginx的rewrite命令,可以实现URL的重写,可在nginx配置文件的server.location.if部分使用,对于rewrite有四种不同的flag. redirect:返回302临 ...
- 网络编程之异步IO
Linux的I/O模型有下面几种:1. 同步阻塞I/O: 用户进程进行I/O操作,一直阻塞到I/O操作完成为止.2. 同步非阻塞I/O: 用户程序可以通过设置文件描述符的属性O_NONBLOCK,I/ ...
- Do Not Try This Problem(分块思想)
题意:https://codeforces.com/group/ikIh7rsWAl/contest/259944/problem/D 给你q个操作,4个数n,a,k,c,从n好位置开始每次加a的位置 ...
- dede按照权重排序dede:list和得的:arclist
dede:list 的方法 1.找到"根目录\include\arc.listview.class.php"文件. 2.修改代码:在文件第727行处添加按weight排序判断代码( ...