今天给各位分享linux中怎么跑多线程的知识,其中也会对linux多线程是怎么实现的进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、Linux下如何实现shell多线程编程以提高应用程序的响应
- 2、Linux C++多线程同步的四种方式
- 3、Linux下如何实现shell多线程编程
- 4、Linux下多线程的如何执行?
- 5、如何进行Linux下多线程的调试
- 6、linux如何实现多线程
1、Linux下如何实现shell多线程编程以提高应用程序的响应
Linux中多线程编程拥有提高应用程序的响应、使多cpu系统更加有效等优点,下面小编将通过Linux下shell多线程编程的例子给大家讲解下多线程编程的过程,一起来了解下吧。
#!/bin/bash
#———————————————————————————–
# 此例子说明了一种用wait、read命令模拟多线程的一种技巧
# 此技巧往往用于多主机检查,比如ssh登录、ping等等这种单进程比较慢而不耗费cpu的情况
# 还说明了多线程的控制
#———————————————————————————–
function a_sub
{
# 此处定义一个函数,作为一个线程(子进程)
sleep 3 # 线程的作用是sleep 3s
}
tmp_fifofile=“/tmp/$.fifo” mkfifo $tmp_fifofile # 新建一个fifo类型的文件
exec 6《》$tmp_fifofile # 将fd6指向fifo类型
rm $tmp_fifofile thread=15 # 此处定义线程数
for
((i=0;i《$thread;i++));do echo
done 》6 # 事实上就是在fd6中放置了$thread个回车符
for
((i=0;i《50;i++));do # 50次循环,可以理解为50个主机,或其他
read -u6 # 一个read -u6命令执行一次,就从fd6中减去一个回车符,然后向下执行,
# fd6中没有回车符的时候,就停在这了,从而实现了线程数量控制
{ # 此处子进程开始执行,被放到后台
a_sub
{ # 此处可以用来判断子进程的逻辑
echo “a_sub is finished”
}
||
{ echo “sub error”
}
echo 》6 # 当进程结束以后,再向fd6中加上一个回车符,即补上了read -u6减去的那个
}
done wait # 等待所有的后台子进程结束
exec 6》- # 关闭df6 exit 0
说明:
此程序中的命令
mkfifo tmpfile
和linux中的命令
mknod tmpfile p
效?果相同。区别是mkfifo为POSIX标准,因此推荐使用它。该命令创建了一个先入先出的管道文件,并为其分配文件标志符6。管道文件是进程之间通信的一种方式,注意这一句很重要
exec 6《》$tmp_fifofile # 将fd6指向fifo类型
如果没有这句,在向文件$tmp_fifofile或者6写入数据时,程序会被阻塞,直到有read读出了管道文件中的数据为止。而执行了上面这一句后就可以在程序运行期间不断向fifo类型的文件写入数据而不会阻塞,并且数据会被保存下来以供read程序读出。
通过运行命令:
time 。/multithread.sh 》/dev/null
最终运算时间: 50/15 = 3组(每组15)+1组(5个《15 组成一个组)= 4组,每组花费时间:3秒,
则 3 * 4 = 12 秒。
传统非多线程的代码 运算时间: 50 * 3 = 150 秒。
上面就是Linux下shell多线程编程的实例介绍了,使用多线程编程还能够改善程序结构,有兴趣的朋友不妨试试看吧。
2、Linux C++多线程同步的四种方式
From :
1.同一个线程内部,指令按照先后顺序执行;但不同线程之间的指令很难说清楚是哪一个先执行,在并发情况下,指令执行的先后顺序由内核决定。
如果运行的结果依赖于不同线程执行的先后的话,那么就会形成竞争条件,在这样的情况下,计算的结果很难预知,所以应该尽量避免竞争条件的形成。
2.最常见的解决竞争条件的方法是:将原先分离的两个指令构成一个不可分割的原子操作,而其他任务不能插入到原子操作中!
3.对多线程来说,同步指的是在一定时间内只允许某一个线程访问某个资源,而在此时间内,不允许其他线程访问该资源!
互斥锁
条件变量
读写锁
信号量
一种特殊的全局变量,拥有lock和unlock两种状态。
unlock的互斥锁可以由某个线程获得,一旦获得,这个互斥锁会锁上变成lock状态,此后只有该线程由权力打开该锁,其他线程想要获得互斥锁,必须得到互斥锁再次被打开之后。
1.互斥锁的初始化, 分为静态初始化和动态初始化.
2.互斥锁的相关属性及分类
(1) attr表示互斥锁的属性;
(2) pshared表示互斥锁的共享属性,由两种取值:
1)PTHREAD_PROCESS_PRIVATE:锁只能用于一个进程内部的两个线程进行互斥(默认情况)
2)PTHREAD_PROCESS_SHARED:锁可用于两个不同进程中的线程进行互斥,使用时还需要在进程共享内存中分配互斥锁,然后为该互斥锁指定属性就可以了。
互斥锁存在缺点:
(1)某个线程正在等待共享数据内某个条件出现。
(2)重复对数据对象加锁和解锁(轮询),但是这样轮询非常耗费时间和资源,而且效率非常低,所以互斥锁不太适合这种情况。
当线程在等待满足某些条件时,使线程进入睡眠状态;一旦条件满足,就换线因等待满足特定条件而睡眠的线程。
程序的效率无疑会大大提高。
1)创建
静态方式:pthread_cond_t cond PTHREAD_COND_INITIALIZER
动态方式:int pthread_cond_init(cond,NULL)
Linux thread 实现的条件变量不支持属性,所以NULL(cond_attr参数)
2)注销
int pthread_cond_destory(cond)
只有没有线程在该条件变量上,该条件变量才能注销,否则返回EBUSY
因为Linux实现的条件变量没有分配什么资源,所以注销动作只包括检查是否有等待线程!(请参考条件变量的底层实现)
3)等待
条件等待:int pthread_cond_wait(cond,mutex)
计时等待:int pthread_cond_timewait(cond,mutex,time)
1.其中计时等待如果在给定时刻前条件没有被满足,则返回ETIMEOUT,结束等待
2.无论那种等待方式,都必须有一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait形成竞争条件!
3.在调用pthread_cond_wait前必须由本线程加锁
4)激发
激发一个等待线程:pthread_cond_signal(cond)
激发所有等待线程:pthread_cond_broadcast(cond)
重要的是,pthread_cond_signal不会存在惊群效应,也就是是它最多给一个等待线程发信号,不会给所有线程发信号唤醒,然后要求他们自己去争抢资源!
pthread_cond_broadcast() 唤醒所有正在pthread_cond_wait()的同一个条件变量的线程。注意:如果等待的多个现场不使用同一个锁,被唤醒的多个线程执行是并发的。
pthread_cond_broadcast pthread_cond_signal
1.读写锁比互斥锁更加具有适用性和并行性
2.读写锁最适用于对数据结构的读操作读操作次数多余写操作次数的场合!
3.锁处于读模式时可以线程共享,而锁处于写模式时只能独占,所以读写锁又叫做共享-独占锁。
4.读写锁有两种策略:强读同步和强写同步
强读同步:
总是给读者更高的优先权,只要写者没有进行写操作,读者就可以获得访问权限
强写同步:
总是给写者更高的优先权,读者只能等到所有正在等待或者执行的写者完成后才能进行读
1)初始化的销毁读写锁
静态初始化:pthread_rwlock_t rwlock=PTHREAD_RWLOCK_INITIALIZER
动态初始化:int pthread_rwlock_init(rwlock,NULL),NULL代表读写锁采用默认属性
销毁读写锁:int pthread_rwlock_destory(rwlock)
在释放某个读写锁的资源之前,需要先通过pthread_rwlock_destory函数对读写锁进行清理。释放由pthread_rwlock_init函数分配的资源
如果你想要读写锁使用非默认属性,则attr不能为NULL,得给attr赋值
int pthread_rwlockattr_init(attr),给attr初始化
int pthread_rwlockattr_destory(attr),销毁attr
2)以写的方式获取锁,以读的方式获取锁,释放读写锁
int pthread_rwlock_rdlock(rwlock),以读的方式获取锁
int pthread_rwlock_wrlock(rwlock),以写的方式获取锁
int pthread_rwlock_unlock(rwlock),释放锁
上面两个获取锁的方式都是阻塞的函数,也就是说获取不到锁的话,调用线程不是立即返回,而是阻塞执行,在需要进行写操作的时候,这种阻塞式获取锁的方式是非常不好的,你想一下,我需要进行写操作,不但没有获取到锁,我还一直在这里等待,大大拖累效率
所以我们应该采用非阻塞的方式获取锁:
int pthread_rwlock_tryrdlock(rwlock)
int pthread_rwlock_trywrlock(rwlock)
互斥锁只允许一个线程进入临界区,而信号量允许多个线程进入临界区。
1)信号量初始化
int sem_init(sem,pshared, v)
pshared为0,表示这个信号量是当前进程的局部信号量。
pshared为1,表示这个信号量可以在多个进程之间共享。
v为信号量的初始值。
返回值:
成功:0,失败:-1
2)信号量值的加减
int sem_wait(sem):以原子操作的方式将信号量的值减去1
int sem_post(sem):以原子操作的方式将信号量的值加上1
3)对信号量进行清理
int sem_destory(sem)
3、Linux下如何实现shell多线程编程
程序代码test.c共两个线程,一个主线程,一个读缓存区的线程:
#include pthread.h
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
char globe_buffer[100];
void *read_buffer_thread(void *arg); //这里先声明一下读缓存的线程,具体实现写在后面了
int main()
{
int res,i;
pthread_t read_thread;
for(i=0;i20;i++)
globe_buffer[i]=i;
printf("\nTest thread : write buffer finish\n");
sleep(3);\\这里的3秒是多余,可以不要。
res = pthread_create(read_thread, NULL, read_buffer_thread, NULL);
if (res != 0)
{
printf("Read Thread creat Error!");
exit(0);
}
sleep(1);
printf("waiting for read thread to finish...\n");
res = pthread_join(read_thread, NULL);
if (res != 0)
{
printf("read thread join failed!\n");
exit(0);
}
printf("read thread test OK, have fun!! exit ByeBye\n");
return 0;
}
void *read_buffer_thread(void *arg)
{
int i,x;
printf("Read buffer thread read data : \n");
for(i=0;i20;i++)
{
x=globe_buffer[i];
printf("%d ",x);
globe_buffer[i]=0;//清空
}
printf("\nread over\n");
}
---------------------------------------------------------------------------------
以上程序编译:
gcc -D_REENTRANT test.c -o test.o –lpthread
运行这个程序:
$ ./test.o:
4、Linux下多线程的如何执行?
主线程结束,则进程结束,属于该进程的所有线程都会结束,可以在主线程中join,也可以在主线程中加死循环。
5、如何进行Linux下多线程的调试
方法一:PS
在ps命令中,“-T”选项可以开启线程查看。下面的命令列出了由进程号为pid的进程创建的所有线程。
1.$ ps -T -p pid
“SID”栏表示线程ID,而“CMD”栏则显示了线程名称。
方法二: Top
top命令可以实时显示各个线程情况。要在top输出中开启线程查看,请调用top命令的“-H”选项,该选项会列出所有Linux线程。在top运行时,你也可以通过按“H”键将线程查看模式切换为开或关。
1.$ top -H
要让top输出某个特定进程pid并检查该进程内运行的线程状况:
$ top -H -p pid
6、linux如何实现多线程
#/bin/bashall_num=10a=$(date +%H%M%S)for num in `seq 1 ${all_num}`do
sleep 1
echo ${num}
done
b=$(date +%H%M%S)
echo -e "startTime:\t$a"echo -e "endTime:\t$b"
linux中怎么跑多线程的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux多线程是怎么实现的、linux中怎么跑多线程的信息别忘了在本站进行查找喔。