linux多线程实例
A. 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多线程编程的实例介绍了,使用多线程编程还能够改善程序结构,有兴趣的朋友不妨试试看吧。
B. linux里面多线程编程问题
mutex是线程锁,多个线程运行,当遇到临界资源,基本上是全局变量时,需要顺序的操作这些资源,不能都去操作,就像数据库里面的原子操作,所以需要用一个锁来同步这些线程,让他们一个一个的来,谁获得锁,谁有权操作。
pthread_mutex_init是对锁进行初始化,一个参数是锁结构体,一个是属性,属性基本为NULL就行。
pthread_mutex_lock用来加锁,加锁后,别的线程运行到这个地方就不能继续运行了,等待解锁。
pthread_mutex_unlock用来解锁。
pthread_mutex_destroy用来销毁锁。
C. LINUX多线程求解,列题是华清远见上面的,代码如下,利用线程互斥锁实现线程的同步
目测是线程退出时没有解开互斥锁,导致其它线程一直在等互斥锁被解开。
以下是修改后的thrd_func函数代码:
//线程函数入口
void*thrd_func(void*arg)
{
intthrd_num=(int)arg;
intdelay_time=0;
intcount=0;
intres;
res=pthread_mutex_lock(&mutex);//互斥锁上锁
if(res)
{
printf("Thread%dlockfailed ",thrd_num);
pthread_exit(NULL);
}
printf("Thread%disstarting ",thrd_num);
for(count=0;count<REPEAT_NUMBER;count++)
{
delay_time=(int)(rand()%5);//随机时间数
sleep(delay_time);
printf(" Thread%d:job%ddelay=%d ",thrd_num,count,delay_time);
}
pthread_mutex_unlock(&mutex);//解开互斥锁
printf("Thread%dfinished ",thrd_num);
pthread_exit(NULL);
}
D. linux下多进程或者多线程编程的问题。新手,望指教!
你好,多进程或多线程,都不会阻塞当前语句代码。为了您的理解,我就大胆举下面两个例子:
多进程:你可以看成是本来是一条路的,现在从中间拆成两条,然后每一条路都有属于自己这条路的代码在运行。
多线程:你可以看成是一条路,然后分出车道,比如左车道和右车道甚至是停车道,然后每条车道都单独通车,其他车道的不能对这条车道进行干扰。
所以,把一条路从中间拆成两条,成本是很高的。但是把一条路分车道,成本就不是很高了。
对于您提出的main函数的疑问,当main函数最后执行完毕,程序退出后,所有的进程包括线程,都会被关闭的,哪怕你的程序中没有关闭,操作系统也会帮你关闭的,现在的操作系统都非常的完善了。当然,也存在有线程或进程不被释放的特殊情况,最好在编程中要记得释放。
E. Linux多线程编程
程序代码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;i<20;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;i<20;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:
F. linux怎么创建多线程
线程是“进程”中某个单一顺序的控制流。也被称为轻量进程。在POSIX线程中,线程体是一个函数。用pthread_create函数来启动这个线程。用pthread_join函数来等待线程结束。在linux中可以通过posix实现
G. java的多线程与linux的多线程的关系
java自己实现了线程库,也就是说java的线程并不和操作系统的线程对应,jvm在操作系统上面是一个进程,当这个进程被操作系统调度到后,jvm内部实现的线程库再调度java线程,为什么是这样呢?考虑到以前的操作系统内核,比如linux,在以前都不直接支持线程,用户线程和内核线程是多对一的关系,solaris一度也是这样,所以java当然心有余而力不足了,你操作系统都不能完美支持线程,你让我实现不是难为我吗?在那个年代,java多线程的调度完全是自主的,操作系统根本不知道java是多线程的,调度策略完全自己实现,单cpu下肯定是分时的,多cpu下就看jvm会不会建立多cpu上的多jvm实例了。
到了后来,操作系统内核纷纷都支持了多线程(windows开始就支持),那么java也要考虑推卸一些责任了,这样java线程就和操作系统线程一一对应或多多对应了,这个时候,如果是一一对应,那么线程的调度完全交给了操作系统内核,当然jvm还保留一些策略足以影响到其内部的线程调度,举个例子,在linux下,只要一个Thread.run就会调用一个fork产生一个线程。
问:java获得cup使用权采用的抢占机制,使用cup的时候是分时机制,这句话对不对?
答:部分对,早期实现,基本可以实现抢占式,但是现代实现,如果系统不支持抢占,那么jvm也无所谓抢占了。
问:多线程使用cup和使用的操作系统有关还是java机制有关(xp是什么机制)
答:早期是java机制实现,现在大部分是操作系统实现的,java机制仅仅保留了相关策略从而影响调度;xp是基于优先级的抢占式调度,其性能很大程度依赖于动态优先级提升
H. C++在linux下怎么多线程
#ifndefTHREAD_H_
#defineTHREAD_H_
#include<unistd.h>
#include<pthread.h>
classRunnable
{
public:
//运行实体
virtualvoidrun()=0;
};
//线程类
classThread:publicRunnable
{
private:
//线程初始化号
staticintthread_init_number;
//当前线程初始化序号
intcurrent_thread_init_number;
//线程体
Runnable*target;
//当前线程的线程ID
pthread_ttid;
//线程的状态
intthread_status;
//线程属性
pthread_attr_tattr;
//线程优先级
sched_paramparam;
//获取执行方法的指针
staticvoid*run0(void*pVoid);
//内部执行方法
void*run1();
//获取线程序号
staticintget_next_thread_num();
public:
//线程的状态-新建
staticconstintTHREAD_STATUS_NEW=0;
//线程的状态-正在运行
staticconstintTHREAD_STATUS_RUNNING=1;
//线程的状态-运行结束
staticconstintTHREAD_STATUS_EXIT=-1;
//构造函数
Thread();
//构造函数
Thread(Runnable*target);
//析构
~Thread();
//线程的运行体
voidrun();
//开始执行线程
boolstart();
//获取线程状态
intget_state();
//等待线程直至退出
voidjoin();
//等待线程退出或者超时
voidjoin(unsignedlongmillis_time);
//比较两个线程时候相同,通过current_thread_init_number判断
booloperator==(constThread*other_pthread);
//获取this线程ID
pthread_tget_thread_id();
//获取当前线程ID
staticpthread_tget_current_thread_id();
//当前线程是否和某个线程相等,通过tid判断
staticboolis_equals(Thread*iTarget);
//设置线程的类型:绑定/非绑定
voidset_thread_scope(boolisSystem);
//获取线程的类型:绑定/非绑定
boolget_thread_scope();
//设置线程的优先级,1-99,其中99为实时,意外的为普通
voidset_thread_priority(intpriority);
//获取线程的优先级
intget_thread_priority();
};
intThread::thread_init_number=1;
inlineintThread::get_next_thread_num()
{
returnthread_init_number++;
}
void*Thread::run0(void*pVoid)
{
Thread*p=(Thread*)pVoid;
p->run1();
returnp;
}
void*Thread::run1()
{
thread_status=THREAD_STATUS_RUNNING;
tid=pthread_self();
run();
thread_status=THREAD_STATUS_EXIT;
tid=0;
pthread_exit(NULL);
}
voidThread::run()
{
if(target!=NULL)
{
(*target).run();
}
}
Thread::Thread()
{
tid=0;
thread_status=THREAD_STATUS_NEW;
current_thread_init_number=get_next_thread_num();
pthread_attr_init(&attr);
}
Thread::Thread(Runnable*iTarget)
{
target=iTarget;
tid=0;
thread_status=THREAD_STATUS_NEW;
current_thread_init_number=get_next_thread_num();
pthread_attr_init(&attr);
}
Thread::~Thread()
{
pthread_attr_destroy(&attr);
}
boolThread::start()
{
returnpthread_create(&tid,&attr,run0,this);
}
inlinepthread_tThread::get_current_thread_id()
{
returnpthread_self();
}
inlinepthread_tThread::get_thread_id()
{
returntid;
}
inlineintThread::get_state()
{
returnthread_status;
}
voidThread::join()
{
if(tid>0)
{
pthread_join(tid,NULL);
}
}
voidThread::join(unsignedlongmillis_time)
{
if(tid==0)
{
return;
}
if(millis_time==0)
{
join();
}
else
{
unsignedlongk=0;
while(thread_status!=THREAD_STATUS_EXIT&&k<=millis_time)
{
usleep(100);
k++;
}
}
}
boolThread::operator==(constThread*other_pthread)
{
if(other_pthread==NULL)
{
returnfalse;
}if(current_thread_init_number==(*other_pthread).current_thread_init_number)
{
returntrue;
}
returnfalse;
}
boolThread::is_equals(Thread*iTarget)
{
if(iTarget==NULL)
{
returnfalse;
}
returnpthread_self()==iTarget->tid;
}
voidThread::set_thread_scope(boolisSystem)
{
if(isSystem)
{
pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);
}
else
{
pthread_attr_setscope(&attr,PTHREAD_SCOPE_PROCESS);
}
}
voidThread::set_thread_priority(intpriority)
{
pthread_attr_getschedparam(&attr,¶m);
param.__sched_priority=priority;
pthread_attr_setschedparam(&attr,¶m);
}
intThread::get_thread_priority(){
pthread_attr_getschedparam(&attr,¶m);
returnparam.__sched_priority;
}
#endif/*THREAD_H_*/
I. 在Linux环境下,对一个设备文件进行多线程读写(两个线程就行),求大神给一个简单的程序。
配置文件为 conf.txt
测试代码如下,注意链接的时候加上 -lpthread 这个参数
#include <stdio.h>
#include <errno.h> //perror()
#include <pthread.h>
#include <unistd.h> //sleep()
#include <time.h> // time()
#include <stdlib.h> //rand()
#define FD "conf.txt"
typedef void *(*fun)(void *);
struct my_struct
{
unsigned time_to_wait;
int n;
};
void *test_thread(struct my_struct *);
int main (int argc, char const *argv[])
{
FILE *fp = fopen(FD, "r");
if (fp == NULL)
{
perror(FD);
return -1;
}
srand((unsigned)time(NULL)); //初始化随机种子
int thread_count;
fscanf(fp, "%d", &thread_count);
fclose(fp);
if (thread_count <= 0)
{
printf("线程数<1,退出程序。\n");
return -1;
}
pthread_t *ptid = (pthread_t *)malloc(sizeof(pthread_t) * thread_count); //保存线程ID
int i;
for (i = 0; i < thread_count; i++)
{
int tw = rand() % thread_count + 1; //随机等待时间
struct my_struct * p = (struct my_struct *)malloc(sizeof(struct my_struct));
if (p == NULL)
{
perror("内存分配错误");
goto ERROR;
}
p->time_to_wait = tw;
p->n = i + 1;
int rval = pthread_create(ptid + i, NULL, (fun) test_thread, (void *)(p)); //注意这里的强制转换(两个)
if (rval != 0)
{
perror("Thread creation failed");
goto ERROR;
}
//sleep(1); //这句加也可以,不加也可以。最开始的时候加上这个是为了让两个线程启动的时候之间有一定的时间差
}
printf("主线程启动\n\n");
fflush(stdout);
for (i = 0; i < thread_count; i++)
{
pthread_join(*(ptid + i), NULL); //等待所有线程退出。
}
printf("\n主线程退出\n");
ERROR:
free(ptid);
return 0;
}
void *test_thread(struct my_struct * p) //线程启动的时候运行的函数
{
printf("第%d个线程启动,预计运行%d秒\n", p->n, p->time_to_wait);
fflush(stdout);
sleep(p->time_to_wait); //让线程等待一段时间
printf("第%d个线程结束\n", p->n);
fflush(stdout);
free(p);
return NULL;
}
你的第二个问题我在网络HI回你了~
J. linux 编写一个多线程程序,要求主线程创建3个子线程,3个子线程在执行时都修改一个他们的共享变量。
void func1(int n)
{
printf("%d",n*10);
}
void func1(int n)
{
printf("%d",n-10);
}
void func1(int n)
{
printf("%d",n/2);
}
int main(void)
{
int n = 10;
pthread_t 1_thread,2_thread,3_thread;
pthread_create(1_thread,NULL,func1,n);
pthread_create(2_thread,NULL,func2,n);
pthread_create(3_thread,NULL,func3,n);
return 0;
}