线程安全即就是在多线程运行的时候,不论线程的调度顺序怎样,最终的结果都是一样的、正确的。那么就说这些线程是安全的。
要保证线程安全需要做到:
(1) 对线程同步,保证同一时刻只有一个线程访问临界资源。
(2)在多线程中使用线程安全的函数(可重入函数),所谓线程安全的函数指的是:如果一个函数能被多个线程同时调用且不发生竟态条件,则我们程它是线程安全的。
可重入函数:就是输入一定的情况下,输出结果必然固定,而且从逻辑上讲要正确,不受任何其他情况的影响。所以可重入函数不能用全局变量、静态变量。
我们期待这样一件事情,主线程对字符串进行分割,子线程对字符串也进行分割,然后进行输出。unsave.c代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>
#include<pthread.h>void* pthread_fun(void* arg)
{char buff[] = "a b c d e f g h i j k";char* p = strtok(buff," ");while(p != NULL){printf("fun:%s\n",p);p = strtok(NULL," ");sleep(1);}pthread_exit(NULL);
}int main()
{pthread_t id;int res = pthread_create(&id,NULL,pthread_fun,NULL);assert(res == 0);char buff[] = "1 2 3 4 5 6 7 8 9 10";char *p = strtok(buff," ");while(p != NULL){printf("main:%s\n",p);p = strtok(NULL," ");sleep(1);}char* s = NULL;pthread_join(id,(void**)s);exit(0);
}

运行结果:

为什么会出现这种结果呢?原因就出在strtok中。我们知道strtok分割字符串,下次会从上次分割的地方继续往后分割,它怎么知道上次分割到哪了呢?指针!每次分割完,指针都会指向分割的结束点,作为下次分割的开始点,而这个指针是一个静态变量,比如一开始主线程先分割,分割完之后,指针指向2,线程pthread_fun开始分割,分割完又叫这个指针指向b,以记录下次分割开始点,再往后,两个线程就继续都从b开始往后分割了,直至把字符串分割完,进程结束。
那么解决方法呢?加锁行吗?不行。因为问题出在strtok内部,出在那个指针上,而且就一个指针,没办法加锁解决。所以strtok这个函数,不适合用在多线程中。所以系统又提供了一个线程安全的版本strtok_r(char* str, const char* delim, char**saveptr)。saveptr是我们自己传入一个指针地址,用我们传入的指针来记录分割结束(开始)点。
修改后的save.c代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>
#include<pthread.h>void* pthread_fun(void* arg)
{char buff[] = "a b c d e f g h i j k";char* q = NULL;char* p = strtok_r(buff," ",&q);while(p != NULL){printf("fun:%s\n",p);p = strtok_r(NULL," ",&q);sleep(1);}pthread_exit(NULL);
}int main()
{pthread_t id;int res = pthread_create(&id,NULL,pthread_fun,NULL);assert(res == 0);char buff[] = "1 2 3 4 5 6 7 8 9 10";char *q = NULL;char *p = strtok_r(buff," ",&q);while(p != NULL){printf("main:%s\n",p);p = strtok_r(NULL," ",&q);sleep(1);}char* s = NULL;pthread_join(id,(void**)s);exit(0);
}

运行结果:

Linux线程——线程安全问题相关推荐

  1. linux动态线程池--原理,这儿的代码不完整

    本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整线程池中线程的数量.文章的最后,我们 ...

  2. linux c 线程的创建、线程等待、线程终止、线程分离

    1. 什么是线程   线程是进程执行内部的一个执行分支,在一个进程内部运行的多种执行流:内部本质上是多个线程在同一个地址空间运行:第一个pcb称之为主线程:有多个线程就有多个执行流:一个进程至少有一个 ...

  3. linux下线程错误码表

    linux下线程错误码在/usr/include/asm-generic/errno-base.h中查看

  4. Linux编程---线程

    首先说一下线程的概念.事实上就是运行在进程的上下文环境中的一个运行流.普通进程仅仅有一条运行流,可是线程提供了多种运行的路径并行的局面. 同一时候,线程还分为核心级线程和用户级线程.主要差别在属于核内 ...

  5. Linux线程——线程创建和基本使用(多线程并发)

    1.线程的概念与实现方式 1.1 线程的概念 概念:线程是进程内部的一条执行序列或执行路径,一个进程可以包含多条线程.线程是进行资源调度和分配的基本单位 . (1)每个进程至少有一条执行路径,所以一个 ...

  6. Linux最大线程数限制及当前线程数查询

    Linux最大线程数限制及当前线程数查询 1.总结系统限制有: /proc/sys/kernel/pid_max #查系统支持的最大线程数,一般会很大,相当于理论值 /proc/sys/kernel/ ...

  7. Linux进程线程学习笔记:运行新程序

    Linux进程线程学习笔记:运行新程序 周银辉 在上一篇中我们说到,当启动一个新进程以后,新进程会复制父进程的大部份上下文并接着运行父进程中的代码,如果我们使新进程不运行原父进程的代码,转而运行另外一 ...

  8. Linux上线程开发API概要(线程)

    进程与线程       典型的UNIX/Linux进程可以看成只有一个控制线程:一个进程在同一时刻只做一件事情.有了多个控制线程后,在程序设计时可以把进程设计成在同一时刻做不止一件事,每个线程各自处理 ...

  9. linux用户空间和内核exit的语义--linux没有线程

    如果你在程序中调用了exit,那么很显然你的程序会退出,可是至于为何会退出那就是库的事情了,我为什么说只是库的事情而不关linux内核的事情呢?那是因为linux内核根本不管用户空间的行为策略.库的策 ...

  10. linux子线程运行的函数_Linux中线程使用详解

    4. 线程的属性 前面还说到过线程创建的时候是有属性的,这个属性由一个线程属性对象来描述.线程属性对象由pthread_attr_init()接口初始化,并由pthread_attr_destory( ...

最新文章

  1. [Spring cloud 一步步实现广告系统] 20. 系统运行测试
  2. 【实验】配置802.1x远端认证
  3. 2018百度之星程序设计大赛 - 资格赛 hdu6345(找区间最小值)
  4. php实现鼠标悬停显示下拉菜单,Html中鼠标悬停显示二级菜单的两种方法
  5. 121 Best Time to Buy and Sell Stock 买卖股票的最佳时机
  6. java为什么被开发者_为什么开发者对Java 9如此的兴奋
  7. 不同范数下的余弦定理_第06题 | 从源头追溯「余弦定理」amp; 文理科知识点的异同...
  8. 加工食品和饮料防腐剂行业调研报告 - 市场现状分析与发展前景预测
  9. DNN深度神经网络、RBM受限玻尔兹曼机、DBN深度置信网络
  10. 【svn】Centos搭建svn服务器环境
  11. 易语言计算机代码,易语言基础教程之简单代码的编写
  12. select用法详解
  13. Vue html转word
  14. 服务器共享文档只读不可复制,局域网共享文件只读不存、共享文件只读不能复制设置法...
  15. 对PX4参数THR_MDL_FAC的理解
  16. 如何取消文件关联,恢复文件默认的图标,最简单的办法!!!!!
  17. Python实现邮箱自动群发工资条
  18. 机械电气自动化常用知识手册
  19. picpick尺子像素大小精度不够准确_如何使用像素标尺在PicPick
  20. Attention Is All You Need论文笔记

热门文章

  1. 一个Delphi写的DES算法, 翻译成C#
  2. C# 网络编程之webBrowser获取网页url和下载网页中图片
  3. 【数据结构与算法】之深入解析“用Rand7()实现Rand10()”的求解思路与算法示例
  4. 【数据结构与算法】之深入解析“颜色分类”的求解思路与算法示例
  5. Swift之深入解析如何自定义操作符
  6. App设计灵感之十二组精美的天气预报App设计案例
  7. PTA —— 基础编程题目集 —— 编程题 —— 7-3 逆序的三位数 (10 分)
  8. python人工智能——机器学习——分类算法-k近邻算法——kaggle案例: Facebook V: Predicting Check Ins
  9. 【机器视觉】 halcon中图像获取
  10. 【机器视觉】 dev_show_tool算子