unix环境高级编程---线程

一、线程概念

如果进程需要完成多个任务的时候,需要对其进行串行化操作。而如果其中一个任务(比如io操作),造成任务执行的挂起。则可以分解任务,将任务分开执行。

其中的每个任务就是所谓的线程。

线程包含了表示进程内执行环境必需的信息。

进程的所有信息对该进程的所有线程都是共享的。包括可执行的程序文本、程序的全局内存和堆内存、栈以及文件描述符。

二、线程创建

新增的线程可以通过pthread_create()函数来创建。

pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void*), void*restrict arg );

当pthread_create成功返回时,由tidp指向的内存单元被设置为新创建线程的线程ID,attr参数用于定制各种不同的线程

属性。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg,如果需要向start_rtn函数传递

的参数不止一个,需要把这些参数放到一个结构体中,然后作为arg参数传入。

在linux下(gcc -pthread -o 文件名 可执行文件名  )进行编译

线程创建的时候并不能保证哪个线程会先运行。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void thread(void)
{
 int i;
 sleep(1);
 for(i=0;i<10;i++)
 printf("This is a pthread.\n");
}

int main(void)
{
 pthread_t id;
 int i,ret;

 ret=pthread_create(&id,NULL,(void *) thread,NULL);
// sleep(1);
 if(ret!=0){
  printf ("Create pthread error!\n");
  exit (1);
 }
 for(i=0;i<3;i++)
  printf("This is the main process.\n");

// pthread_join(id,NULL);

 pthread_exit(NULL);

 return (0);
}

三、线程同步

当多个控制线程共享相同的内存的时候,需要确保每个线程看到一致的数据视图。

为了解决数据同步的问题,线程使用锁,也就是在同一时间只允许一个 线程访问该变量。

1、互斥量

我们可以通过使用pthread的互斥接口保护数据,确保同一时间只有一个线程访问数据。

互斥变量用pthread_mutex_t数据类型来表示。

对数据量加锁需要调用pthread_mutex_lock

对互斥量解锁,需要调用pthread_mutex_unlock

下面的代码没有经过加锁,应该是1和2连续输出的,但现在运行到一半时候可能被另一个线程打进来。

#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
#include <string.h>

void* th_func(void* arg){
        int i;
        for(i=0; i<5; i++){
                printf("1\n");
                sleep(1);
                printf("2\n");
        }
}

int main(void){
        int ret;
        pthread_t tid1,tid2;

        ret = pthread_create(&tid1, NULL, th_func, NULL);
        if(ret != 0){
                printf("pthread_create:%s\n",strerror(ret));
                return -1;
        }

        ret = pthread_create(&tid2, NULL, th_func, NULL);
        if(ret != 0){
                printf("pthread_create:%s\n",strerror(ret));
                return -1;
        }

        sleep(15);
        return 0;
}
1
1
2
1
2
1
2
1
2
1
2
1
2
1
2
1
2
1
2
2

如果加上线程锁之后:

就避免了以上现象的发生。

  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <malloc.h>
  4. #include <string.h>
  5. pthread_mutex_t *mutex;
  6. void* th_func(void* arg){
  7. int i;
  8. for(i=0; i<5; i++){
  9. pthread_mutex_lock(mutex);
  10. printf("1\n");
  11. sleep(1);
  12. printf("2\n");
  13. pthread_mutex_unlock(mutex);
  14. }
  15. }
  16. int main(void){
  17. int ret,result = 0;
  18. pthread_t tid1,tid2;
  19. mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
  20. if(mutex == NULL){
  21. perror("malloc");
  22. result = -1;
  23. goto FINALLY;
  24. }
  25. pthread_mutex_init(mutex,NULL);
  26. ret = pthread_create(&tid1, NULL, th_func, NULL);
  27. if(ret != 0){
  28. printf("pthread_create:%s\n",strerror(ret));
  29. result = -1;
  30. goto FINALLY;
  31. }
  32. ret = pthread_detach(tid1);
  33. if(ret != 0){
  34. printf("pthread_detach:%s\n",strerror(ret));
  35. result = -1;
  36. goto FINALLY;
  37. }
  38. ret = pthread_create(&tid2, NULL, th_func, NULL);
  39. if(ret != 0){
  40. printf("pthread_create:%s\n",strerror(ret));
  41. result = -1;
  42. goto FINALLY;
  43. }
  44. ret = pthread_detach(tid2);
  45. if(ret != 0){
  46. printf("pthread_detach:%s\n",strerror(ret));
  47. result = -1;
  48. goto FINALLY;
  49. }
  50. sleep(15);
  51. FINALLY:
  52. if(mutex != NULL){
  53. pthread_mutex_destroy(mutex);
  54. free(mutex);
  55. }
  56. return result;
  57. }

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-04 04:11:04

unix环境高级编程---线程的相关文章

(九) 一起学 Unix 环境高级编程 (APUE) 之 线程

. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录 (四) 一起学 Unix 环境高级编程 (APUE) 之 系统数据文件和信息 (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境 (六) 一起学 Unix 环境高级编程 (APUE) 之 进程控制 (七) 一起学 Unix 环境高级编程 (APUE)

Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字 . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录 (四) 一起学 Unix 环境高级编程 (APUE) 之 系统数据文件和信息 (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境 (六) 一起学 Unix 环境高级编程 (APU

《UNIX环境高级编程》学习心得 一

本文内容大部分摘自<UNIX环境高级编程>,附有部分个人心得. 1.unix体系结构 从严格意义上来说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境.我们通常将这种软件称为内核(kernel),因为它相对较小,而且位于环境核心.如图显示unix体系结构. 内核接口被称为系统调用(system call).公用函数库构建在系统调用接口之上,应用程序既可食用公用函数库,也可以使用系统调用.shell是一个特殊的应用程序,为运行其他应用程序提供了一个接口. 从广义上来讲,操作系

Unix环境高级编程

Advanced Programming in the UNIX Environment Second Edition Unix 环境高级编程 第二版 目录: 第一章:UNIX基础知识 第二章:UNIX标准化及实现 第三章:文件I/O 第四章:文件和目录 第五章:标准I/O库 第六章:系统数据文件盒信息 第七章:进程环境 第八章:进程控制 第九章:进程关系 第十章:信号 第十一章:线程 第十二章:线程控制 第十三章:守护线程 第十四章:高级I/O 第十五章:进程间通信 第十六章:网络IPC:套接

《Unix环境高级编程》读书笔记 第7章-进程环境

1. main函数 int main( int argc, char *argv[] ); argc是命令行参数的数目,包括程序名在内 argv是指向参数的各个指针所构成的数组,即指针数组 当内核执行C程序时(使用exec函数),在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址——这是由连接器设置的,而连接器则是由C编译器调用.启动例程从内核取得命令行参数和环境变量值,然后按上述方式调用main函数做好安排. 2. 进程终止 有8种方式使进程终止,其中5种

《UNIX环境高级编程(第3版)》

<UNIX环境高级编程(第3版)> 基本信息 原书名:Advanced Programming in the UNIX Environment (3rd Edition) (Addison-Wesley Professional Computing Series) 原出版社: Addison-Wesley Professional 作者: (美)W. Richard Stevens    Stephen A. Rago 译者: 戚正伟 张亚英 尤晋元 出版社:人民邮电出版社 ISBN:9787

(十二) 一起学 Unix 环境高级编程 (APUE) 之 进程间通信(IPC)

. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录 (四) 一起学 Unix 环境高级编程 (APUE) 之 系统数据文件和信息 (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境 (六) 一起学 Unix 环境高级编程 (APUE) 之 进程控制 (七) 一起学 Unix 环境高级编程 (APUE)

(十一) 一起学 Unix 环境高级编程 (APUE) 之 高级 IO

. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录 (四) 一起学 Unix 环境高级编程 (APUE) 之 系统数据文件和信息 (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境 (六) 一起学 Unix 环境高级编程 (APUE) 之 进程控制 (七) 一起学 Unix 环境高级编程 (APUE)

《Unix环境高级编程》读书笔记 第3章-文件I/O

1. 引言 Unix系统的大多数文件I/O只需用到5个函数:open.read.write.lseek以及close 本章描述的函数经常被称为不带缓冲的I/O.术语不带缓冲指的是在用户的进程中对其不会自动缓冲,每个read和write都调用内核中的一个系统调用.但是,所有磁盘I/O都要经过内核的块缓存区(也称为内核的缓冲区高速缓存).唯一例外的是对原始磁盘设备的I/O. 2. 文件描述符 对于内核而言,所有打开的文件都通过文件描述符引用.文件描述符是一个非负整数,其变化范围是0~OPEN_MAX