`
duyouhua1214
  • 浏览: 228179 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

C语言多线程的相关函数和实例

 
阅读更多

 线程相关操作

    一 pthread_t

    pthread_t在头文件/usr/include/bits/pthreadtypes.h中定义:
      typedef unsigned long int pthread_t;
      它是一个线程的标识符。

 

    二 pthread_create

    函数pthread_create用来创建一个线程,它的原型为:
      extern int pthread_create __P ((pthread_t *__thread, __const pthread_attr_t *__attr,
      void *(*__start_routine) (void *), void *__arg));
      第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。这里,我们的函数thread不需要参数,所以最后一个参数设为空指针。第二个参数我们也设为空指针,这样将生成默认属性的线程。对线程属性的设定和修改我们将在下一节阐述。当创建线程成功时,函数返回0,若不为0则说明创建线程失败,常见的错误返回代码为EAGAIN和EINVAL。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。

    三 pthread_join pthread_exit
      
    函数pthread_join用来等待一个线程的结束。函数原型为:
      extern int pthread_join __P ((pthread_t __th, void **__thread_return));
      第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。它的函数原型为:
      extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));
      唯一的参数是函数的返回代码,只要pthread_join中的第二个参数thread_return不是NULL,这个值将被传递给 thread_return。最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码ESRCH。
      在这一节里,我们编写了一个最简单的线程,并掌握了最常用的三个函数pthread_create,pthread_join和pthread_exit。下面,我们来了解线程的一些常用属性以及如何设置这些属性。
 

    互斥锁相关

    互斥锁用来保证一段时间内只有一个线程在执行一段代码。

    一 pthread_mutex_init

    函数pthread_mutex_init用来生成一个互斥锁。NULL参数表明使用默认属性。如果需要声明特定属性的互斥锁,须调用函数 pthread_mutexattr_init。函数pthread_mutexattr_setpshared和函数 pthread_mutexattr_settype用来设置互斥锁属性。前一个函数设置属性pshared,它有两个取值, PTHREAD_PROCESS_PRIVATE和PTHREAD_PROCESS_SHARED。前者用来不同进程中的线程同步,后者用于同步本进程的不同线程。在上面的例子中,我们使用的是默认属性PTHREAD_PROCESS_ PRIVATE。后者用来设置互斥锁类型,可选的类型有PTHREAD_MUTEX_NORMAL、PTHREAD_MUTEX_ERRORCHECK、 PTHREAD_MUTEX_RECURSIVE和PTHREAD _MUTEX_DEFAULT。它们分别定义了不同的上所、解锁机制,一般情况下,选用最后一个默认属性。

 

    二 pthread_mutex_lock pthread_mutex_unlock pthread_delay_np

       pthread_mutex_lock声明开始用互斥锁上锁,此后的代码直至调用pthread_mutex_unlock为止,均被上锁,即同一时间只能被一个线程调用执行。当一个线程执行到pthread_mutex_lock处时,如果该锁此时被另一个线程使用,那此线程被阻塞,即程序将等待到另一个线程释放此互斥锁。

下面先来一个实例。我们通过创建两个线程来实现对一个数的递加。

01 #include <PTHREAD.H>
02 #include <STDIO.H>
03 #include <SYS time.h="">
04 #include <STRING.H>
05 #define MAX 10
06 pthread_t thread[2];
07 pthread_mutex_t mut;
08 int number=0, i;
09 void *thread1()
10 {
11         printf ("thread1 : I'm thread 1\n");
12         for (i = 0; i < MAX; i++)
13         {
14                 printf("thread1 : number = %d\n",number);
15                 pthread_mutex_lock(&mut);
16                         number++;
17                 pthread_mutex_unlock(&mut);
18                 sleep(2);
19         }
20         printf("thread1 :主函数在等我完成任务吗?\n");
21         pthread_exit(NULL);
22 }
23 void *thread2()
24 {
25         printf("thread2 : I'm thread 2\n");
26         for (i = 0; i < MAX; i++)
27         {
28                 printf("thread2 : number = %d\n",number);
29                 pthread_mutex_lock(&mut);
30                         number++;
31                 pthread_mutex_unlock(&mut);
32                 sleep(3);
33         }
34         printf("thread2 :主函数在等我完成任务吗?\n");
35         pthread_exit(NULL);
36 }
37 void thread_create(void)
38 {
39         int temp;
40         memset(&thread, 0, sizeof(thread));          //comment1
41         /*创建线程*/
42         if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0)       //comment2
43                 printf("线程1创建失败!\n");
44         else
45                 printf("线程1被创建\n");
46         if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0)  //comment3
47                 printf("线程2创建失败");
48         else
49                 printf("线程2被创建\n");
50 }
51 void thread_wait(void)
52 {
53         /*等待线程结束*/
54         if(thread[0] !=0) {                   //comment4
55                 pthread_join(thread[0],NULL);
56                 printf("线程1已经结束\n");
57         }
58         if(thread[1] !=0) {                //comment5
59                 pthread_join(thread[1],NULL);
60                 printf("线程2已经结束\n");
61         }
62 }
63 int main()
64 {
65         /*用默认属性初始化互斥锁*/
66         pthread_mutex_init(&mut,NULL);
67         printf("我是主函数哦,我正在创建线程,呵呵\n");
68         thread_create();
69         printf("我是主函数哦,我正在等待线程完成任务阿,呵呵\n");
70         thread_wait();
71         return 0;
72 }</STRING.H></STDIO.H></PTHREAD.H>

 

下面我们先来编译、执行一下

引文:

    falcon@falcon:~/program/c/code/ftp$ gcc -lpthread -o thread_example thread_example.c
    falcon@falcon:~/program/c/code/ftp$ ./thread_example
    我是主函数哦,我正在创建线程,呵呵
    线程1被创建
    线程2被创建
    我是主函数哦,我正在等待线程完成任务阿,呵呵
    thread1 : I'm thread 1
    thread1 : number = 0
    thread2 : I'm thread 2
    thread2 : number = 1
    thread1 : number = 2
    thread2 : number = 3
    thread1 : number = 4
    thread2 : number = 5
    thread1 : number = 6
    thread1 : number = 7
    thread2 : number = 8
    thread1 : number = 9
    thread2 : number = 10
    thread1 :主函数在等我完成任务吗?
    线程1已经结束
    thread2 :主函数在等我完成任务吗?
    线程2已经结束

转自:http://www.linuxpig.com/2011/02/c-duoxiancheng-shili/

分享到:
评论

相关推荐

    Windows多线程编程技术与实例.pdf

     本书语言通俗易懂,内容丰富翔实,突出了以实例为中心的特点,既适合具有一定c++和VC编程基础的高校相关专业学生选作多线程编程的学习用书,也适用于具有一定实际编程经验的中高级开发人员作为学习多线程编程思想...

    Python实现的调用C语言函数功能简单实例

    本文实例讲述了Python实现的调用C语言函数功能。分享给大家供大家参考,具体如下: 实例参考python cookbook 中的15.1节中的例子P612页 先把 c文件编译成 so文件 gcc a.c -fpic -shared -o lib.so 通过上面编译...

    tcl实例入门教程(包括常用的socket多线程xml解析数据库操作大量实例)

    知识点覆盖比较全面,要个20分不过分吧,有几本书认真讲过那些常用模块: socket, 数据库操作,xml解析,多线程,最具体的做法多半是一带而过,我可是一个例子一个例子做出来的。 把目录发给大家看看: 2.1 第1课:...

    Linux线程同步之信号C语言实例

    linux中向某个线程发送信号,若没有对该信号的处理函数,则会导致程序结束。 如下面的程序,创建一个线程,主线程向其发送一个信号,会导致程序立即结束 #include #include &lt;pthread&gt; pthread_t t; void* run...

    77G 22套C语言 C++ 数据结构 程序设计视频课程合集 C丨C++相关学习视频全套视频教程

    ABG2C_字符和字符串函数.mp4 ABG2C_循环.mp4 ABG2C_数学函数.mp4 ABG2C_数学运算.mp4 ABG2C_更高级的运算符.mp4 ABG2C_注释.mp4 ABG2C_测试多个值.mp4 ABG2C_终止循环.mp4 ABG2C_表达式还能用来做什么.mp4 ...

    宋劲彬的嵌入式C语言一站式编程

    1.2. socket地址的数据类型及相关函数 2. 基于TCP协议的网络程序 2.1. 最简单的TCP网络程序 2.2. 错误处理与读写控制 2.3. 把client改为交互式输入 2.4. 使用fork并发处理多个client的请求 2.5. setsockopt 2.6. ...

    基于C语言实现的嵌入式电机状态机(含源码)

    前言 背景 内外事件 事件数据 状态转变 状态机模块 电机实例 外部事件 州数 状态函数 状态图 状态机对象 过渡图 新的状态机步骤 状态引擎 生成事件 不使用堆 离心机测试实例 多线程安全

    Visual C++ 6.0编程实例详解.part2

    第9章 多任务和多线程 9.1 多线程概念 9.2 创建与终止线程 9.2.1 AfxBeginThread函数 9.2.2 创建用户界面线程 9.2.3 创建辅助线程 9.2.4 终止线程 9.2.5 线程的优先级 9.3 线程通信 9.3.1 ...

    Visual C++ 6.0编程实例详解.part1

    第9章 多任务和多线程 9.1 多线程概念 9.2 创建与终止线程 9.2.1 AfxBeginThread函数 9.2.2 创建用户界面线程 9.2.3 创建辅助线程 9.2.4 终止线程 9.2.5 线程的优先级 9.3 线程通信 9.3.1 ...

    c语言编程要点word

    罗列的很详细,也很实用,总共二十一章,每小节都有精彩编码实例讲解,绝对是我的私藏,下面罗列前几章和后面的c语言参数表的一部分。。 1.1 什么是局部程序块(local block)? 1.2 可以把变量保存在局部程序块中吗?...

    static 用法

    static关键字是C, C++中都存在的关键字, 它主要有三...另外, 在设计类的多线程操作时, 由于POSIX库下的线程函数pthread_create()要求是全局的, 普通成员函数无法直接做为线程函数, 可以考虑用Static成员函数做线程函数

    Linux C程序设计大全

    3.4 与函数有关的优化 3.4.1 函数调用与程序优化 3.4.2 变量存储优化 3.5 编写多文件程序——变量的存储类别 3.5.1 存储类别 3.5.2 static变量的作用——改变变量的生命期 3.5.3 static变量的作用——实现封装和模块...

    嵌入式应用层开发要学习什么?

    精通嵌入式Linux下的程序设计,精通嵌入式Linux开发环境,强化对Linux应用开发的理解和编码调试的能力,包括系统编程、文件I/O、多进程和多线程、网络编程、GUI图形界面编程、数据库。 第四阶段嵌入式入门阶段-ARM...

    Linux C 一站式学习

    1.2. socket地址的数据类型及相关函数 2. 基于TCP协议的网络程序 2.1. 最简单的TCP网络程序 2.2. 错误处理与读写控制 2.3. 把client改为交互式输入 2.4. 使用fork并发处理多个client的请求 2.5. setsockopt 2.6. ...

    C/C++笔试题(附答案,华为面试题系列)

    Linux 支持内核级的多线程 13.C++中什么数据分配在栈或堆中,New分配数据是在近堆还是远堆中? 答:栈: 存放局部变量,函数调用参数,函数返回值,函数返回地址。由系统管理 堆: 程序运行时动态申请,new 和 malloc...

    python cookbook(第3版)

    15.8 C和Python中的线程混用 15.9 用WSIG包装C代码 15.10 用Cython包装C代码 15.11 用Cython写高性能的数组操作 15.12 将函数指针转换为可调用对象 15.13 传递NULL结尾的字符串给C函数库 15.14 传递Unicode...

Global site tag (gtag.js) - Google Analytics