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 < ...
随机推荐
- Golang开源项目
谷歌官方维护了一个基于go语言的开源项目列表: https://github.com/golang/go/wiki/Projects 其中有非常多的优秀项目值得学习,有几百行代码适合新手阅读的项目,也 ...
- godot新手教程2[godot常用代码用法]
Godot概念: 在godot内,使用的语言是GDScript,大部分代码风格是和python一样. 在GDScript内代码段结束是换到下一行即可,不需要也不能添加”;”号,(注意:代码段结束后不能 ...
- 一步步分析Java深拷贝的两种方式-clone和序列化
今天遇到一道面试题,询问深拷贝的两种方法.主要就是clone方法和序列化方法.今天就来分析一下这两种方式如何实现深拷贝.如果想跳过解析的朋友,直奔"重点来了!"寻找答案. clon ...
- 在VMware上安装centos
Windows,VMware和Centos三者的关系 VMware安装.centos安装 在 VMware 上安装 CentOS 第 1 步:打开 VMware,点击创建新的虚拟机 第 2 步:选择典 ...
- idea的eclipse快速定位link with editor
eclipse的link with editor,个人感觉非常有用的一个功能 idea也有这个功能autoscroll from source
- JavaSE基础(四)--Java基本数据类型
Java 基本数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. 因此,通过定义不 ...
- [CF132C] Logo Turtle
[CF132C] Logo Turtle , Luogu A turtle moves following by logos.(length is \(N\)) \(F\) means "m ...
- Kettle无法打开文件资源库
问题: Kettle无法打开文件资源库. 问题描述: 新建文件资源库之后,资源库路径中有中文路径.退出kettle之后,再次进去发现没有了右上角的connect按钮了. 原因: kettle的repo ...
- VMWare虚拟机15.X局域网网络配置(修改网卡)
最近在搞几台虚拟机来学习分布式和大数据的相关技术,首先先要把虚拟机搞起来,搞起虚拟机第一步先安装系统,接着配置网络 vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式).N ...
- CSS实现单选按钮
import React from 'react' import PropTypes from 'prop-types' import CX from 'classnames' import _ fr ...