Linux多线程编程小结
作者:网络转载 发布时间:[ 2014/11/4 11:51:46 ] 推荐标签:操作系统 Linux 多线程编程
5.2用相互排斥量进行线程同步
还有一种用在多线程程序中同步?问的方法是使用相互排斥量。它同意程序猿锁住某个对象,使得每次仅仅能有一个线程?问它。为了控制对关键代码的?问,必须在进入这段代码之前锁住一个相互排斥量,然后在完毕操作之后解锁它。
用于相互排斥量的基本函数和用于信号量的函数很类似:
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t, *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destory(pthread_mutex_t *mutex);
与其它函数一样,成功时返回0,失败时将返回错误代码,但这些函数并不设置errno,所以必须对函数的返回代码进行检查。相互排斥量的属性设置这里不讨论,因此设置成NULL。
我们用相互排斥量来重写刚才的代码例如以下:
编译这个程序:
gcc -D_REENTRANT thread4.c -o thread4 –lpthread
执行这个程序:
$ ./thread4
Input some text. Enter 'end' to finish
123
You input 3 characters
1234
You input 4 characters
12345
You input 5 characters
end
You input 3 characters
Thread joined
6.线程的属性
之前我们并未谈及到线程的属性,能够控制的线程属性是许多的,这里面仅仅列举一些经常使用的。
如在前面的演示样例中,我们都使用的pthread_join同步线程,但事实上有些情况下,我们并不须要。如:主线程为服务线程,而第二个线程为数据备份线程,备份工作完毕之后,第二个线程能够直接终止了,它没有必要再返回到主线程中。因此,我们能够创建一个“脱离线程”。
以下介绍几个经常使用的函数:
(1)int pthread_attr_init (pthread_attr_t* attr);
功能:对线程属性变量的初始化。
attr:线程属性。
函数返回值:成功:0,失败:-1
(2) int pthread_attr_setscope (pthread_attr_t* attr, int scope);
功能:设置线程绑定属性。
attr:线程属性。
scope:PTHREAD_SCOPE_SYSTEM(绑定);PTHREAD_SCOPE_PROCESS(非绑定)
函数返回值:成功:0,失败:-1
(3) int pthread_attr_setdetachstate (pthread_attr_t* attr, int detachstate);
功能:设置线程分离属性。
attr:线程属性。
detachstate:PTHREAD_CREATE_DETACHED(分离);PTHREAD_CREATE_JOINABLE(非分离)
函数返回值:成功:0,失败:-1
(4) int pthread_attr_setschedpolicy(pthread_attr_t* attr, int policy);
功能:设置创建线程的调度策略。
attr:线程属性;
policy:线程调度策略:SCHED_FIFO、SCHED_RR和SCHED_OTHER。
函数返回值:成功:0,失败:-1
(5) int pthread_attr_setschedparam (pthread_attr_t* attr, struct sched_param* param);
功能:设置线程优先级。
attr:线程属性。
param:线程优先级。
函数返回值:成功:0,失败:-1
(6) int pthread_attr_destroy (pthread_attr_t* attr);
功能:对线程属性变量的销毁。
attr:线程属性。
函数返回值:成功:0,失败:-1
(7)其它
int pthread_attr_setguardsize(pthread_attr_t* attr,size_t guardsize);//设置新创建线程栈的保护区大小。
int pthread_attr_setinheritsched(pthread_attr_t* attr, int inheritsched);//决定如何设置新创建线程的调度属性。
int pthread_attr_setstack(pthread_attr_t* attr, void* stackader,size_t stacksize);//两者共同决定了线程栈的基地址以及堆栈的小尺寸(以字节为单位)。
int pthread_attr_setstackaddr(pthread_attr_t* attr, void* stackader);//决定了新创建线程的栈的基地址。
int pthread_attr_setstacksize(pthread_attr_t* attr, size_t stacksize);//决定了新创建线程的栈的小尺寸(以字节为单位)。
例:创建优先级为10的线程。
pthread_attr_t attr;
struct sched_param param;
pthread_attr_init(&attr);
pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM); //绑定
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); //分离
pthread_attr_setschedpolicy(&attr, SCHED_RR);
param.sched_priority = 10;
pthread_attr_setschedparam(&attr, ¶m);
pthread_create(xxx, &attr, xxx, xxx);
pthread_attr_destroy(&attr);
以下实现一个脱离线程的程序,创建一个线程,其属性设置为脱离状态。子线程结束时,要使用pthread_exit,原来的主线程不再等待与子线程又一次合并。代码例如以下:
编译这个程序:
gcc -D_REENTRANT thread5.c -o thread5 –lpthread
执行这个程序:
$ ./thread5
thread_function is running. Argument: hello world!
Waiting for thread to finished...
Waiting for thread to finished...
Waiting for thread to finished...
Waiting for thread to finished...
Second thread setting finished flag, and exiting now
Other thread finished!
通过设置线程的属性,我们还能够控制线程的调试,其方式与设置脱离状态是一样的。
7.取消一个线程
有时,我们想让一个线程能够要求还有一个线程终止,线程有方法做到这一点,与信号处理一样,线程能够在被要求终止时改变其行为。
先来看用于请求一个线程终止的函数:
#include <pthread.h>
int pthread_cancel(pthread_t thread);
这个函数简单易懂,提供一个线程标识符,我们能够发送请求来取消它。
线程能够用pthread_setcancelstate设置自己的取消状态。
#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
?数说明:
state:能够是PTHREAD_CANCEL_ENABLE同意线程接收取消请求,也能够是PTHREAD_CANCEL_DISABLE忽略取消请求。
oldstate:获取先前的取消状态。假设对它没兴趣,能够简单地设置为NULL。假设取消请求被接受了,线程能够进入第二个控制层次,用pthread_setcanceltype设置取消类型。
#include <pthread.h>
int pthread_setcanceltype(int type, int *oldtype);
?数说明:
type:能够取PTHREAD_CANCEL_ASYNCHRONOUS,它将使得在接收到取消请求后马上?取行动;还有一个是PTHREAD_CANCEL_DEFERRED,它将使得在接收到取消请求后,一直等待直到线程运行了下述函数之中的一个后才?取行动:pthread_join、pthread_cond_wait、pthread_cond_timedwait、pthread_testcancel、sem_wait或sigwait。
oldtype:同意保存先前的状态,假设不想知道先前的状态,能够传递NULL。
默认情况下,线程在启动时的取消状态为PTHREAD_CANCEL_ENABLE,取消类型是PTHREAD_CANCEL_DEFERRED。
以下编写代码thread6.c,主线程向它创建的线程发送一个取消请求。
编译这个程序:
gcc -D_REENTRANT thread6.c -o thread6 –lpthread
执行这个程序:
$ ./thread6
thread_function is running...
Thread is still running (0)...
Thread is still running (1)...
Thread is still running (2)...
Thread is still running (3)...
Canceling thread...
Waiting for thread to finished...
8.多线程
之前,我们所编写的代码里面都不过创建了一个线程,如今我们来演示一下怎样创建一个多线程的程序。
编译这个程序:
gcc -D_REENTRANT thread7.c -o thread7 –lpthread
执行这个程序:
$ ./thread7
thread_function is running. Argument was 0
thread_function is running. Argument was 1
thread_function is running. Argument was 2
thread_function is running. Argument was 3
thread_function is running. Argument was 4
Bye from 1
thread_function is running. Argument was 5
Waiting for threads to finished...
Bye from 5
Picked up a thread:6
Bye from 0
Bye from 2
Bye from 3
Bye from 4
Picked up a thread:5
Picked up a thread:4
Picked up a thread:3
Picked up a thread:2
Picked up a thread:1
All done
9.小结
本文主要介绍了Linux环境下的多线程编程,介绍了信号量和相互排斥量、线程属性控制、线程同步、线程终止、取消线程及多线程并发。
本文比较简单,仅仅作为初学Linux多线程编程入门之用。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Linux下开源的DDR压力测试工具曝Linux恶意软件:让树莓派设备挖掘数字货币linux系统中不同颜色的文件夹及根目录介绍软件测试工程师必知必会Linux命令Linux下DNS服务器配置如何成为不可替代的Linux运维工程师?详解Linux进程(作业)的查看和杀死Linux 日志定时轮询流程详解比特币勒索病毒不只Windows系统有,Linux版的来了Linux日志定时轮询流程详解Linux iommu和vfio概念空间解构Linux系统如何低于TCP洪水攻击Linux无损调整分区大小Linux下防火墙配置实例Linux使用Jexus托管Asp.Net Core应用程序Linux中引号的那些事

sales@spasvo.com