C语言多线程pthread库-互斥锁

来源:互联网 发布:软件项目经理jd 编辑:程序博客网 时间:2024/05/29 11:49

C语言多线程pthread库相关函数说明

线程相关操作说明

  一 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处时,如果该锁此时被另一个线程使用,那此线程被阻塞,即程序将等待到另一个线程释放此互斥锁。

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

  view source

  print?

  01 #include

  02 #include

  03 #include

  04 #include

  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);[nextpage]

  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 }

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

  引文:

  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已经结束

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 富贵竹叶子变黄怎么办 富贵竹的叶子黄了怎么办 土栽富贵竹发黄怎么办 富贵竹的黄叶子怎么办 土培富贵竹发黄怎么办 富贵竹根变黄了怎么办 富贵竹叶子尖发黄怎么办 富贵竹新叶子发黄怎么办 富贵竹杆变黄了怎么办 水培观音竹叶子发黄怎么办 富贵竹叶子根部发黄怎么办 观音竹叶子干了怎么办 富贵竹叶子发干怎么办 观音竹老叶发黄怎么办 发财树缺营养怎么办 富贵竹根部长芽怎么办 门口的竹子发黄怎么办 富贵竹长根了怎么办 水养竹子太长怎么办 海棠根腐烂了怎么办 水竹根腐烂了怎么办 水培富贵竹黑根怎么办 转运竹根部发黑怎么办 富贵竹跟泡烂怎么办 富贵竹根烂了怎么办 富贵竹的须变黑怎么办 泡富贵竹水发臭怎么办 富贵竹水变黑了怎么办 水观音叶子黄了怎么办 富贵竹根部腐烂发臭怎么办 富贵竹根部发粘怎么办 水竹草叶子发黄怎么办 水竹叶子心发黄怎么办 塔竹叶子发黄怎么办 铁树叶有发黄怎么办 铁树夏天叶发黄怎么办 铁树的叶尖发黄怎么办 铁树叶子发黄是怎么办 榕树盆景长蜜怎么办 六月雪叶子枯萎了怎么办 小叶冬青掉叶子怎么办