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 < ...
随机推荐
- vim实现批量注释和批量删除注释
批量注释 1.进入文档,vim test.txt 后,按住ctrl+v进入VISUAL BLOCK模式,上下选择需要注释的行 2.按大写键,再按i,或者直接按shift+i,进入INSERT模式,输入 ...
- shell脚本执行出现“期待整数表达式”
在执行shell时一直出现“integer expression expected”,找了很久也没发现那个地方出错.翻了笔记发现-le并不错啊,甚至还怀疑零是不是整数还特意上网搜了下 -_- . 最后 ...
- 【ARM-Linux开发】C语言getcwd()函数:取得当前的工作目录
相关函数:get_current_dir_name, getwd, chdir 头文件:#include <unistd.h> 定义函数:char * getcwd(char * buf, ...
- OpenGL.英文
1. emission 英 [iˈmɪʃn] 美 [iˈmɪʃn] 排放 n. (光.热.气等的)发出,射出,排放;排放物;散发物 material 英 [məˈtɪəriəl] 美 [məˈtɪri ...
- Linux sar命令
yum install sysstat 安装 sar [root@wang /]# sar -n DEV Linux -.el6.x86_64 (wang) 2016年12月21日 _x86_64_ ...
- 解决git rebase操作后推送远端分支不成功的问题
转:解决git rebase操作后推送远端分支不成功的问题 前段时间在工作中同事在rebase时遇到一个问题来问我,今天突然想起来觉得有必要记录一下. 在我们日常工作中,经常使用git座位代码管理工具 ...
- nginx源码安装(CentOS版)
准备工作: 1) 配好网易yum源 登录此网站(http://mirrors.163.com/.help/centos.html),下载相应版本的yum源至服务器的/etc/yum.repos.d/目 ...
- [CF132C] Logo Turtle
[CF132C] Logo Turtle , Luogu A turtle moves following by logos.(length is \(N\)) \(F\) means "m ...
- 数据库连接池——C3P0&Druid(快速入门)
数据库连接池--C3P0&Druid (一) 数据库连接池 每一个事物都有其存在的意义,在初学jdbc的时候,我们建立数据库连接对象后,会对其进行释放,但是数据库连接的建立和关闭是非常消耗资源 ...
- Python if __name__ == '__main__': 理解
if __name__ == '__main__':是为了区分.py文件是自己直接被执行还是被其他文件调用. 当.py文件直接被执行时,默认的是 __name__ = '__main__',因此条件成 ...