原文:https://www.cnblogs.com/yorkyang/p/7804733.html

线程的优点:

  • 减少系统调度开销,不占有独立的资源,切换速度快,执行效率高。
  • 线程间通信方便,可共享资源。
  • 改善程序设计结构,功能复杂的进程可以分为多个独立的线程分别执行,模块性更强。

  线程分为:用户态线程和核心态线程。

  用户态的多线程程序在运行时不许要特定的内核支持,同一个进程的线程之间进行切换时,不需要调用系统调用。

  核心态线程的实现方法允许不同进程中的的线程按照相同的调度方法进行调度,有利于发挥多处理器的并发优势。

线程创建:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*),void *arg);
//thread 指向线程标识符的指针,使用这个标识符来引用新线程
//attr 设置线程属性,设为NULL则生成默认属性的线程
//start_routine 线程运行函数的起始位置
//arg 线程运行函数的参数

线程终止:

1.通过线程自身结束

void pthread_exit(void *rval_ptr);
//rval_ptr是函数的返回代码,相当于线程的退出码 2.通过同一进程的其他线程来结束 int pthread_cancel(pthread_t tid);
//tid是要结束线程的标识符

下面的函数用于阻塞等待一个线程的结束

int pthread_join(pthread_t thread, void **return_ptr)
//创建线程,输出当前系统的时间

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<unistd.h>
#include<pthread.h> void print_currentTime(void)
{
time_t ct;
ct=time(NULL);
//ctime:将秒数转换成字符串
printf("current time is : '%s'",ctime(&ct));
pthread_exit("Time thread finished!\n");
} int main()
{
int ret;
void *thread_result;
pthread_t new_thread; ret=pthread_create(&new_thread,NULL,(void*)print_currentTime,NULL);
if(ret!=0){
perror("thread creation failed!\n");
exit(EXIT_FAILURE);
} printf("waiting for new thread....\n");
ret=pthread_join(new_thread,&thread_result);
if(ret!=0){
perror("thread join failed!\n");
exit(EXIT_FAILURE);
} printf("thread joined, returned: %s\n",(char*)thread_result);
return 0;
}
//编译时候注意: gcc thread_date.c -o thread_date -lpthread

线程属性:

线程属性主要包括分离属性,绑定属性,调度属性,堆栈属性,继承属性等,结构为pthread_attr_t。

属性设置函数:

int pthread_attr_init(pthread_attr_t *attr)
//attr是指向属性结构的指针
//注意:此函数必须在调用pthread_creater()函数之前调用

这里提到了一个概念“轻进程(Light Weight Process, LWP)”,位于用户层与系统层之间的内核线程。系统对线程资源的分配以及对线程的控制是通过轻进程来实现的,一个轻进程可以控制一个或多个线程。

获取线程绑定状态函数:

int pthread_attr_getscope(pthread_attr_t *attr, int *scope)
//scope返回绑定属性的状态

设置线程绑定属性函数:

int pthread_attr_setscope(pthread_attr_t* attr, int scope)
//scope是要绑定的类型

获得线程优先级函数:

int pthread_attr_getschedparam(pthread_attr_t *attr, const struct sched_param *param)
//param中存放线程的调度参数信息

设置线程优先级函数:

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)

获取调度策略函数:

int pthread_attr_getschedpolicy(pthread_attr *attr, int *policy)
//调度策略存放在policy中

设置调度策略函数:

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)

获取并发级别函数:

int pthread_getconcurrency(void)

设置并发级别函数:

int pthread_setconcurrency(int new_level)

多线程同步技术:

线程同步机制主要有:互斥量,信号量,条件变量,读写锁等。

互斥量:

数据类型为pthread_mytex_t,主要函数:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_mutex_lock(pthread_mutex_t *mutex); //阻塞调用
int pthread_mutex_trylock(pthread_mutex_t *mutex); //非阻塞调用
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//mutex是定义的pthread_mutex_t的指针,mutex_attr是互斥量的属性结构

例子:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h> pthread_mutex_t mutex;
int count=0;
char msg_buf[64]; void setMsg_Func(void)
{
while(count>0){
pthread_mutex_lock(&mutex);
memset(msg_buf,0,64);
sprintf(msg_buf,"count=%d.\n",count--);
pthread_mutex_unlock(&mutex);
srand((int)time(0));
sleep(rand()%3);
}
pthread_exit(0);
} void printMsg_Func(void)
{
while(count>=0){
pthread_mutex_lock(&mutex);
printf("%s",msg_buf);
pthread_mutex_unlock(&mutex);
if(0==count)
break;
srand((int)time(0));
sleep(rand()%3);
}
} int main()
{
int ret;
pthread_t set_thread;
count=4;
pthread_mutex_init(&mutex,NULL);
ret=pthread_create(&set_thread,NULL,(void*)&setMsg_Func,NULL);
if(ret!=0){
perror("thread creation failed!\n");
exit(EXIT_FAILURE);
} printMsg_Func();
ret=pthread_join(set_thread,NULL);
if(ret!=0){
perror("thread creation failed!\n");
exit(EXIT_FAILURE);
}
printf("Finished!\n");
pthread_mutex_destroy(&mutex);
return 0;
}

但是要注意,如果使用互斥量过程中,如果两个线程试图同时占用两个资源,并锁定,可能造成死锁。

条件变量:

  只使用互斥量很可能造成死锁,为此可以加入条件变量。条件变量允许线程阻塞和等待另一个线程发送信号,使用条件变量可以以原子方式阻塞线程,直到满足某个条件为止。

  互斥量主要用来保证对临界区的互斥进入,而条件变量则用于线程的阻塞等待。

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);     //创建条件变量
int pthread_cond_signal(pthread_cond_t *cond); //用来释放被阻塞在条件变量cond上的进程
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); //使线程阻塞
int pthread_cond_broadcast(pthread_cond_t *cond); //用来唤醒所有阻塞在条件变量cond上的线程
int pthread_cond_timewait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
//使线程阻塞,与wait不同,它经过abstime时间后,无论条件是否满足,都会释放 int pthread_cond_destroy(pthread_cond_t *cond); //cond是一个指向结构pthread_cond_t的指针
//cond_attr是条件变量的属性结构指针

例子:

//创建两个线程,偶数时进程1给变量加1,奇数时进程2给变量加1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h> #define MAX_COUNT 9 pthread_mutex_t mutex;
pthread_cond_t cond;
int count=0; void addCount_odd_Func(void)
{
pthread_mutex_lock(&mutex);
while(count<MAX_COUNT){
if(count%2==1){
count++;
printf("addcout_odd_Func():count=%d.\n",count);
pthread_cond_signal(&cond);
}
else
pthread_cond_wait(&cond,&mutex);
}
pthread_mutex_unlock(&mutex);
} void addCount_even_Func(void)
{
pthread_mutex_lock(&mutex);
while(count<MAX_COUNT){
if(count%2==0){
count++;
printf("addCount_even_Func:count=%d.\n",count);
pthread_cond_signal(&cond);
}
else
pthread_cond_wait(&cond,&mutex);
}
pthread_mutex_unlock(&mutex);
} int main(int argc, char **argv)
{
int ret;
pthread_t odd_thread,even_thread;
pthread_attr_t thread_attr;
count=0; pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
ret=pthread_attr_init(&thread_attr);
if(ret!=0){
perror("attribute creation failed!");
exit(EXIT_FAILURE);
} pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED); ret=pthread_create(&odd_thread,&thread_attr,(void*)&addCount_odd_Func,NULL);
if(ret!=0){
perror("thread creation failed!");
exit(EXIT_FAILURE);
} ret=pthread_create(&even_thread,&thread_attr,(void*)&addCount_even_Func,NULL);
if(ret!=0){
perror("thread creation failed!");
exit(EXIT_FAILURE);
} while(count<MAX_COUNT); printf("Finished!");
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex); return 0;
}

C语言中的多线程的更多相关文章

  1. C语言中的多线程编程

    很久很久以前,我对C语言的了解并不是很多,我最早听说多线程编程是用Java,其实C语言也有多线程编程,而且更为简单.方便.强大.下面就让我们简单领略一下Unix C语言环境下的多线程编程吧! 下面先看 ...

  2. C语言中关键字volatile的含义【转】

    本文转载自:http://m.jb51.net/article/37489.htm 本篇文章是对C语言中关键字volatile的含义进行了详细的分析介绍,需要的朋友参考下 volatile 的意思是“ ...

  3. C/C++——C++变量的作用域与生命周期,C语言中变量的作用域和生命周期

    全局变量 作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件.) 生命周期:程序运行期一直存在 引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量. 内 ...

  4. Java中的多线程总结(转)

      1.多线程概述 当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程.主要以下几个优点: 线程之间很容易实现共享内存 创建线程代价较小 Java语言内置多线程功能支持 2.线 ...

  5. Go语言中的管道(Channel)总结

    管道(Channel)是Go语言中比较重要的部分,经常在Go中的并发中使用.今天尝试对Go语言的管道来做以下总结.总结的形式采用问答式的方法,让答案更有目的性. Q1.管道是什么? 管道是Go语言在语 ...

  6. C语言中关键字auto、static、register、const、volatile、extern的作用

    原文:C语言中关键字auto.static.register.const.volatile.extern的作用 关键字auto.static.register.const.volatile.exter ...

  7. OS X 和iOS 中的多线程技术(下)

    OS X 和iOS 中的多线程技术(下) 上篇文章中介绍了 pthread 和 NSThread 两种多线程的方式,本文将继续介绍 GCD 和 NSOperation 这两种方式.. 1.GCD 1. ...

  8. 【worker】js中的多线程

    因为下个项目中要用到一些倒计时的功能,所以就提前准备了一下,省的到时候出现一下界面不友好和一些其他的事情.正好趁着这个机会也加深一下html5中的多线程worker的用法和理解. Worker简介 J ...

  9. C语言编程(多线程)

    C语言中多线程编程包括的文件:#include<pthread.h>(linux环境下) pthread_t //线程函数返回类型 pthread_mutrex_t //互斥锁类型 int ...

随机推荐

  1. STM8 工程模版

    在st官网下载STM8固件库 拷贝固件库到工程目录下 再创建两个目录 user:存放用户文件.自己编写的源文件 project:存放工程文件 拷贝stm8s_conf.h到user目录下 AIR 创建 ...

  2. Eclipse workspace被锁定

    重新打开Eclipse时,提示如下: Workspace Unavailable: Workspace in use or cannot be created, choose a different ...

  3. 极度舒适的 Python 入门教程,小猪佩奇也能学会~

    编程几乎已经成为现代人的一门必修课,特别是 Python ,不仅长期霸占编程趋势榜.薪资榜第一,还屡屡进入小学教材,甚至成为浙江省信息技术高考项目-- 今天,小编带来了一门极度舒适的 Python 入 ...

  4. 用js刷剑指offer(复杂链表的复制)

    题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

  5. Ajax 的简介与使用

    一.什么是Ajax Ajax 的全称是 Asynchronous JavaScript and XML(即异步的 JavaScript 和 XML),是一种在无需重新加载整个网页的情况下,能够更新部分 ...

  6. android:duplicateParentState属性使用场景

    对于这个属性的使用也是在偶然的时候发现的,之前从未使用它,所以有必要阐述一下它的用法,什么场景会要用它这个属性,在我不知道之前这个属性之前,也同样能实现效果,但是当我知道它的存在之后,我肯定在某种场景 ...

  7. 1121 Django操作

    目录 Django前戏 一.课程导读 1.web应用 2.c/s b/s 架构 3.Python Web框架 二.原生socket服务 三.http协议 什么是http协议 四大特性 http工作原理 ...

  8. machine learning(15) --Regularization:Regularized logistic regression

    Regularization:Regularized logistic regression without regularization 当features很多时会出现overfitting现象,图 ...

  9. 并发编程:Thread和Runable-01

      1.继承Thread类(不推荐) 代码很简单,就不说了 public class ThreadTest02 { public static void main(String[] args) { n ...

  10. Python基本的语法知识

    1. 编程语言的介绍 低级语言:机器语言--------计算机内部只能接受二进制代码,故用0或者1表示的指令称为机器指令,全部的机器指令构成了计算机的机器语言. 汇编语言--------实质上跟机器语 ...