Linux多线程编程

来源:互联网 发布:淘宝上有没有枪卖 编辑:程序博客网 时间:2024/05/17 10:04

原文地址 http://johnylai.blog.sohu.com/63406924.html

 

典型的线程包括一个运行时间系统,它可以按透明的方式来管理线程。通常线程包包括对线程的创建和删除,以及对互斥和条件变量的调用。POSIX标准线程库具有这些调用。这些包还提供线程的动态创建和删除,因此,直到运行时间之前,线程的个数不必知道。

       线程具有一个ID、一个堆栈、一个执行优先权,以及执行的开始地址。POSIX线程通过pthread_t类型的ID来引用。pthread_t其实就是无符号长整型,在文件/usr/include/bits/pthreadtypes.h有如下定义:

       typedef unsigned long int pthread_t;

       线程的内部数据结构也包含调度和使用信息。进程的线程共享进程的完整地址空间,它们能够修改全局变量,访问打开的文件描述符,或用别的方式相互作用。

1、  pthread_create函数

如果线程可在进程的执行期间的任意时刻被创建,并且线程的数量事先没有必要指定,这样的线程称为动态线程。在POSIX中,线程是用pthread_create动态的创建的。pthread_create能创建线程,并将它放入就绪队列。创建线程需要调用pthread_create,该函数的定义如下所示:

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void*(*start_routine)(void *),void *arg);

该函数的第1个参数thread将指向创建线程的ID。线程的属性是由attr指向的属性对象来包容的。如果attr为NULL,新线程具有缺省的属性。第3个参数start_routine是线程开始执行时调用的函数名字。start_routine占用一个参数arg,它是一个指向viod的指针。start_routine返回一个指向viod的指针,此指针被空作时pthread_jion的退出状态。

函数pthread_create在成功调用时返回0,失败时返回-1。

2、  pthread_self函数

在创建线程之后,可以调用pthread_self得到线程的ID,该函数的定义如下所示:

#include <pthread.h>

pthread_t pthread_self(void);

3、  pthread_exit函数

与进程退出时调用exit类似,线程退出时也需要调用pthread_exit,它的定义如下:

#include <pthread.h>

void pthread_exit(void* retval);

函数pthread_exit终止调用的线程。参数retval的值对pthread_join函数的成功由实际意义。然而,pthread_exit的retval必须指定,在线程退出时它才退出的数据,因此它不能够作为正在退出的线程的自动局部数据被分配。

函数pthread_exit在成功调用时返回0,失败时返回-1。

4、  pthread_join函数

在成功创建线程之后,可以调用pthread_join将创建的线程加入到原进程中去,pthread_join的定义如下所示:

#include <pthread.h>

int pthread_join(pthread_t th,void **thread_return);

如果调用了pthread_join,那么进程会等待线程调用pthread_exit之后才退出,这个函数的作用类似于wait系统调用。pthread_join的第1个参数th为所创建线程的ID,第2个参数指向线程的退出码。

函数pthread_join在成功调用时返回0,失败时返回-1。

5、例子

/*mutl.c*/

#include <stdio.h>

#include<errno.h>

#include<pthread.h>

#include<unistd.h>

#define THREAD_NUM 2

 

void *my_thread(void *arg)

{

       pthread_t id;

       int *nump;

       int num;

       int retval;

      

nump=(int *)(arg);

num=*nump;

printf(“thread %d:start!/n”,num);

id=pthread_self();

printf(“thread %d: ID is %d!/n”,num,id);

retval=100+num;

printf(“thread %d:exit with %d!/n”,num.retval);

pthread_exit(&retval);

}

int main()

{

       int count;

       pthread thread[THREAD_NUM+1];

       int *retval[THREAD_NUM+1];

       int arg[THREAD_NUM+1];

 

       count=1;

       while(count<=THREAD_NUM)

       {

              printf(“Create thread %d!/n”,count);

              arg[count]=count;

             

              if(pthread_create(&thread[count],NULL,my_thread,(void*)(&arg[count]))!=0)

              {

                     fprintf(stderr,”Count not create thread %d:%s!/n”,count,strerror(errno));

}

count++;

}//while

for(count=1;count<=THREAD_NUM;count++)

{

       if(pthread_join(thread[count],(void **)(&retval[count]))!=0)

       {

              fprintf(stderr,”No thread %d to join:%s!/n”,count,strerr(errno));

}//if

else

{

       printf(“Thread %d returned %d!/n”,count,*retval[count]);

}

}//for

}

这个例子的编译运行如下:

[root@linux]# gcc –o mutl mutl.c /usr/lib/libpthread.so

[root@linux]#mutl

Create thread 1

Create thread 2

thread 1:start

thread 1:ID is 1026

thread 1:exit with 101

thread 1 return 101

thread 2 started

thread 2:ID si 2051

thread 2:exit with 102

thread 2 return 102

而对于用arm-linux-gcc编译的时候后面需要加上-lpthread

参考:毛曙福       《linux C高级程序员指南》国防工业出版社

多线程互斥方法

在使用互斥变量之前需要定义互斥变量:

pthread_mutex_t        mutex;

然后对变量进行初始化,也即向内核申请互斥变量

pthread_mutex_init(&mutex, NULL);

进入临界区之前需要对变量进行加锁:

pthread_mutex_lock(&mutex);

       ……………………

最后退出临界区的时候需要进行解锁

pthread_mutex_unlock(&mutex);

 

原创粉丝点击