`
abcde5342376
  • 浏览: 34614 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Linux 多线程编程实验知识整理

阅读更多
1 Introduction
不用介绍了吧…
2 Thread Concepts
1. Thread由下面部分组成:
a. Thread ID
b. Stack
c. Policy
d. Signal mask
e. Errno
f. Thread-Specific Data
3 Thread Identification
1. pthread_t用于表示Thread ID,具体内容根据实现的不同而不同,有可能是一个Structure,因此不能将其看作为整数
2. pthread_equal函数用于比较两个pthread_t是否相等
#i nclude <pthread.h>
int pthread_equal(pthread_t tid1, pthread_t tid2)
3. pthread_self函数用于获得本线程的thread id
#i nclude <pthread.h>
pthread _t pthread_self(void);
4 Thread Creation
1. 创建线程可以调用pthread_create函数:
#i nclude <pthread.h>
int pthread_create(
pthread_t *restrict tidp,
const pthread_attr_t *restrict attr,
void *(*start_rtn)(void *), void *restrict arg);
a. pthread_t *restrict tidp:返回最后创建出来的Thread的Thread ID
b. const pthread_attr_t *restrict attr:指定线程的Attributes,后面会讲道,现在可以用NULL
c. void *(*start_rtn)(void *):指定线程函数指针,该函数返回一个void *,参数也为void*
d. void *restrict arg:传入给线程函数的参数
e. 返回错误值。
2. pthread函数在出错的时候不会设置errno,而是直接返回错误值
3. 在Linux 系统下面,在老的内核中,由于Thread也被看作是一种特殊,可共享地址空间和资源的Process,因此在同一个Process中创建的不同 Thread具有不同的Process ID(调用getpid获得)。而在新的2.6内核之中,Linux采用了NPTL(Native POSIX Thread Library)线程模型(可以参考http://en.wikipedia.org/wiki/Native_POSIX_Thread_Libraryhttp://www-128.ibm.com/developerworks/linux/library/l-threading.html?ca=dgr-lnxw07LinuxThreadsAndNPTL),在该线程模型下同一进程下不同线程调用getpid返回同一个PID。
4. 不能对创建的新线程和当前创建者线程的运行顺序作出任何假设
5 Thread Termination
1. exit, _Exit, _exit用于中止当前进程,而非线程
2. 中止线程可以有三种方式:
a. 在线程函数中return
b. 被同一进程中的另外的线程Cancel掉
c. 线程调用pthread_exit函数
3. pthread_exit和pthread_join函数的用法:
a. 线程A调用pthread_join(B, &rval_ptr),被Block,进入Detached状态(如果已经进入Detached状态,则pthread_join函数返回EINVAL)。如果对B的结束代码不感兴趣,rval_ptr可以传NULL。
b. 线程B调用pthread_exit(rval_ptr),退出线程B,结束代码为rval_ptr。注意rval_ptr指向的内存的生命周期,不应该指向B的Stack中的数据。
c. 线程A恢复运行,pthread_join函数调用结束,线程B的结束代码被保存到rval_ptr参数中去。如果线程B被Cancel,那么rval_ptr的值就是PTHREAD_CANCELLED。
两个函数原型如下:
#i nclude <pthread.h>
void pthread_exit(void *rval_ptr);
int pthread_join(pthread_t thread, void **rval_ptr);
4. 一个Thread可以要求另外一个Thread被Cancel,通过调用pthread_cancel函数:
#i nclude <pthread.h>
void pthread_cancel(pthread_t tid)
该函数会使指定线程如同调用了pthread_exit(PTHREAD_CANCELLED)。不过,指定线程可以选择忽略或者进行自己的处理,在后面会讲到。此外,该函数不会导致Block,只是发送Cancel这个请求。
5. 线程可以安排在它退出的时候,某些函数自动被调用,类似atexit()函数。需要调用如下函数:
#i nclude <pthread.h>
void pthread_cleanup_push(void (*rtn)(void *), void *arg);
void pthread_cleanup_pop(int execute);
这两个函数维护一个函数指针的Stack,可以把函数指针和函数参数值push/pop。执行的顺序则是从栈顶到栈底,也就是和push的顺序相反。
在下面情况下pthread_cleanup_push所指定的thread cleanup handlers会被调用:
a. 调用pthread_exit
b. 相应cancel请求
c. 以非0参数调用pthread_cleanup_pop()。(如果以0调用pthread_cleanup_pop(),那么handler不会被调用
有一个比较怪异的要求是,由于这两个函数可能由宏的方式来实现,因此这两个函数的调用必须得是在同一个Scope之中,并且配对,因为在pthread_cleanup_push的实现中可能有一个 {,而 pthread_cleanup_pop可能有一个}。因此,一般情况下,这两个函数是用于处理意外情况用的,举例如下:
void *thread_func(void *arg)
{
pthread_cleanup_push(cleanup, “handler”)
// do something
Pthread_cleanup_pop(0);
return((void *)0)
}
6. 进程函数和线程函数的相关性:
Process Primitive
Thread Primitive
Description
fork
pthread_create
创建新的控制流
exit
pthread_exit
退出已有的控制流
waitpid
pthread_join
等待控制流并获得结束代码
atexit
pthread_cleanup_push
注册在控制流退出时候被调用的函数
getpid
pthread_self
获得控制流的id
abort
pthread_cancel
请求非正常退出
7. 缺省情况下,一个线程A的结束状态被保存下来直到pthread_join为该线程被调用过,也就是说即使线程A已经结束,只要没有线程B调用 pthread_join(A),A的退出状态则一直被保存。而当线程处于Detached状态之时,党线程退出的时候,其资源可以立刻被回收,那么这个退出状态也丢失了。在这个状态下,无法为该线程调用pthread_join函数。我们可以通过调用pthread_detach函数来使指定线程进入 Detach状态:
#i nclude <pthread.h>
int pthread_detach(pthread_t tid);
通过修改调用pthread_create函数的attr参数,我们可以指定一个线程在创建之后立刻就进入Detached状态
6 Thread Synchronization
1. 互斥量:Mutex
a. 用于互斥访问
b. 类型:pthread_mutex_t,必须被初始化为PTHREAD_MUTEX_INITIALIZER(用于静态分配的mutex,等价于 pthread_mutex_init(…, NULL))或者调用pthread_mutex_init。Mutex也应该用pthread_mutex_destroy来销毁。这两个函数原型如下:(attr的具体含义下一章讨论)
#i nclude <pthread.h>
int pthread_mutex_init(
pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr)
int pthread_mutex_destroy(pthread_mutex_t *mutex);
c. pthread_mutex_lock 用于Lock Mutex,如果Mutex已经被Lock,该函数调用会Block直到Mutex被Unlock,然后该函数会Lock Mutex并返回。pthread_mutex_trylock类似,只是当Mutex被Lock的时候不会Block,而是返回一个错误值EBUSY。 pthread_mutex_unlock则是unlock一个mutex。这三个函数原型如下:
#i nclude <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
2. 读写锁:Reader-Writer Locks
a. 多个线程可以同时获得读锁(Reader-Writer lock in read mode),但是只有一个线程能够获得写锁(Reader-writer lock in write mode)
b. 读写锁有三种状态
i. 一个或者多个线程获得读锁,其他线程无法获得写锁
ii. 一个线程获得写锁,其他线程无法获得读锁
iii. 没有线程获得此读写锁
c. 类型为pthread_rwlock_t
d. 创建和关闭方法如下:
#i nclude <pthread.h>
int pthread_rwlock_init(
pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr)
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
e. 获得读写锁的方法如下:
#i nclude <pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
pthread_rwlock_rdlock:获得读锁
pthread_rwlock_wrlock:获得写锁
pthread_rwlock_unlock:释放锁,不管是读锁还是写锁都是调用此函数
注意具体实现可能对同时获得读锁的线程个数有限制,所以在调用 pthread_rwlock_rdlock的时候需要检查错误值,而另外两个pthread_rwlock_wrlock和 pthread_rwlock_unlock则一般不用检查,如果我们代码写的正确的话。
分享到:
评论

相关推荐

    实验二、嵌入式Linux多线程编程实验

    实验二的目的是让学生深入理解嵌入式Linux环境下的多线程编程,这涉及到对线程概念、创建和管理的理解,以及如何在编程中引入线程库。线程是操作系统资源调度的基本单位,允许在一个进程中并发执行多个执行路径,...

    嵌入式软件开发技术:第5章 嵌入式Linux多线程编程.ppt

    本章节将详细介绍嵌入式Linux多线程编程的基本概念、线程的创建、同步和互斥、线程属性、多线程实验等方面的知识点。 1. 线程基本概念 在Linux系统中,线程是进程内独立的一条运行路线,处理器调度的最小单元,也...

    linux多线程编程.pdf

    Linux多线程编程是操作系统中并发程序设计的一个重要领域,它允许开发者在同一...通过以上知识点的介绍,我们可以看到Linux多线程编程的复杂性和丰富性。掌握这些知识对于设计高效、稳定、多线程的软件系统至关重要。

    Linux多线程服务端编程:使用muduo+C网络库

    Linux多线程服务端编程:使用muduo+C网络库.pdf Linux多线程服务端编程:使用muduo+C网络库.pdfLinux多线程服务端编程:使用muduo+C网络库.pdfLinux多线程服务端编程:使用muduo+C网络库.pdfLinux多线程服务端编程:...

    Linux多线程编程手册

    Linux多线程编程是计算机编程中一个高级主题,涉及到...手册中不仅详细介绍了多线程编程的理论知识,还包括了大量编程示例和最佳实践建议,对于任何希望精通Linux多线程编程的开发者来说,都是一份不可多得的参考资料。

    Linux下的多线程编程.pdf

    "Linux下的多线程编程" Linux下的多线程编程是一种高效的程序设计方法,它可以将一个程序的任务划分为多个部分,每个部分是一个顺序控制流。多线程编程可以实现并行计算,高效利用多处理器,并且具有许多优点,如...

    Linux下C语言多线程编程实例

    Linux 下 C 语言多线程编程实例 Linux 下的多线程编程是一种非常重要的技术,在实际应用中有非常广泛的应用范围。多线程编程可以大大提高程序的执行效率和响应速度。但是,多线程编程也存在一些复杂性,例如线程...

    Linux多线程服务端编程,高清无水印!~

    Linux多线程服务端编程,高清无水印!~

    Linux多线程服务端编程

    Linux多线程服务端编程是陈硕大神的一本linux服务端开发实战书籍。

    Linux系统下的多线程编程入门.pdf

    在Linux系统下进行多线程编程是开发高效并发应用程序的关键技术之一。本文将深入探讨Linux环境中的多线程概念、创建与管理线程的方法、线程同步与通信机制,以及多线程编程中可能遇到的问题和解决策略。 一、多线程...

    Linux编程技术-实验4 多线程编程.doc

    本实验报告的主要内容是关于Linux多线程编程的技术实验,实验目的主要是掌握线程的概念及基本操作方法,掌握线程间同步互斥基本原理,并能够利用互斥锁进行线程间同步操作。 一、实验目的: 1. 掌握线程的概念及...

    Linux多线程编程_linux_

    总之,Linux多线程编程涉及的内容广泛,包括线程的创建、同步、通信、资源管理等多个方面。掌握这些知识点对于开发高效、稳定的多线程应用程序至关重要。通过深入学习和实践,你将能够充分利用Linux的多线程特性来...

    嵌入式Linux应用程序开发第9章多线程编程

    "嵌入式Linux应用程序开发第9章多线程编程" 本章主要讲解了 Linux 中的多线程编程,包括 Linux 线程的基本概念、创建及使用、属性设置、同步与互斥问题的处理等内容。通过学习本章,读者将掌握 Linux 中线程的基本...

    linux 多线程编程

    Linux 多线程编程 Linux 多线程编程是操作系统课程设计的重要组成部分,多线程技术早在 60 年代就被提出,但真正应用多线程到操作系统中去,是在 80 年代中期,solaris 是这方面的佼佼者。传统的 Unix 也支持线程的...

    实验二 嵌入式Linux多线程编程实验

    ### 嵌入式Linux多线程编程实验知识点解析 #### 一、Fibonacci(斐波那契)序列多线程生成实验 **实验背景与目标:** 本实验旨在利用多线程技术,在嵌入式Linux环境下生成斐波那契数列。通过此实验,学生能够加深...

    linux下多线程编程

    Linux 下多线程编程 Linux 下的多线程编程遵循 POSIX 线程接口,称为 pthread。编写 Linux 下的多线程程序,需要使用头文件 pthread.h,连接时需要使用库 libpthread.a。 Linux 下 pthread 的实现是通过系统调用 ...

Global site tag (gtag.js) - Google Analytics