编译器支持多线程
① 新人求教.Perl怎么编译能支持多线程,要加什么配置选项吗
我在fedora或者ubuntu下运行代码,用的分别是v5.10.1和v5.13.5
都出现:
This Perl not built to support threads
Compilation failed in require at rnclogcol.pl line 11.
BEGIN failed--compilation aborted at rnclogcol.pl line 11.
line 11是 use threads;
threads模块也从CPAN下载装好了,还是不行;去网上查了下,似乎说是我的perl不支持多线程,要重新编译,请问要怎么编译阿?
我现在是直接 sh Configure -de 默认的,然后直接make,make test,make install这么编译的。。。
② C语言可以实现 中断 和 多线程 这类功能吗
“晕,C语言不是灰常强大,无所不能吗?怎么有人说C语言不能实现 中断 和多线程??”这句话要分两部分来说,首先“晕,C语言不是灰常强大,无所不能吗?”。没有任何一种语言可以无所不能,原因很简单,任何的语言都脱离不了编译工具,而编译工具脱离不了编译环境。由于编译环境的不同,因此编译工具也有所不同,有得只针对java,有得指针对C++,有得只针对C#。不管C语言多厉害,如果编译工具不支持,那也没有办法在这个编译工具上编译,以至于没有办法在那个编译工具的编译环境中运行。所以不能说无所不能。
“怎么有人说C语言不能实现 中断 和多线程啊”,这是一个概念性问题。纯粹的C语言只是一个工具,更多的是一种定义,一种格式,可以抽象成一种风格。就像定义一个整型变量i。为什么你不能用integer i定义,非得int i。例如函数的编写形式,命名规则等等。假如按照C语言的这些规则来编写程序,同时编译工具支持C语言,提供中断库,还有多线程库,那么C语言同样也可以实现中断和多线程。举个例子:例如你手头上只有一个TC编译工具,虽然他支持C语言,但是只能编译16位的DOS程序,碍于这个编译工具的局限性,所以你永远也写不出像Windows操作系统那种带窗口界面的Win32程序,也不能写一个针对.NET框架的网络服务程序。同样的,假如你要开发一个Windows软件,使用VC编译器,而这个编译工具本身带多线程库,同时支持Windows系统的很多调用,所以你完全可以以C语言的风格在这个编译器中调用各种Win32 SDK,开发一个多线程的Windows应用程序。假如你要使用中断,在Windows环境下可以使用微软提供的DDK(驱动开发包),他同样支持C语言,那么你就可以通过这个开发包调用很多中断。在linux环境下,不需要开发包就可以直接调用,因为Linux自带了很多系统调用都是开放的。头文件声明直接就在Linux文件系统的Sys目录下。所以说他仅仅是一种风格。依赖于编译环境的系统调用同样也依赖于编译环境提供的链接库。
③ VC++6.0编译器中怎么设置编译选项为多线程
/MT
“Project Settings”
选择“C/C++”页面标签,然后在“Category”下拉式清单方块中选择“Code Generation”。在“Use Run-Time Library”下拉式清单方块中,可以看到用于“Release”设定的“Single-Threaded”和用于Debug设定的“Debug Single-Threaded”。将这些分别改为“Multithreaded”和“Debug Multithreaded”。
④ C++多线程编程要用到哪些库如何编译这些库
千万别以为现在的C++没有原生的多线程库
OpenMP 是一个多线程库,不过他还需要编译器的支持,好在现在绝大多数都已经支持(这个可能是目前最流行的原生多线程库了)
C++的标准头process.h(太老的没有,2002年后的基本都有)中有操作进程和执行环境的函数,能实现简单的进程级或线程级并行操作。
使用起来非常非常方便。windows平台的C语言编译工具也都有这个头,unix平台上的unistd.h跟这个头很相似,函数名与用法也基本一样。
还有一些其他的第三方多线程库,你可以网上搜搜,但是注意是否跨平台等问题
如果你要使用操作系统相关的多线程API,那么也就没什么选择余地,windows上只能用windows的多线程API (参考MSDN) unix同理
OpenMP的优点是跨平台,功能丰富强大(例如提供了各种锁、信号等),代码改动也比较小,使用起来也非常方便快捷。缺点是没有像直接用系统API时透明感,毕竟使用系统API时,程序员完全控制了逻辑,非常直观,当然这也带来了错误风险和代码复杂度
⑤ 如何用GCC在linux下编译C语言程序
在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器,假设我们有下面一个非常简单的源程序(hello.c):
int main(int argc,char **argv)
{
printf("Hello Linux
");
}
要编译这个程序,我们只要在命令行下执如橘耐行:
gcc -o hello hello.c
gcc 编译器就会为我们生成一个hello的可执行渣春文件.执行./hello就可以看到程
序的输出结果了
⑥ 编译器如何处理多线程程序
这是一个多线程例子,里面只有两个线程,是生产者/消费者模式,已编译通过,注释很详细,
如下:
/* 以生产者和消费者模型问题来阐述Linux线程的控制和通信你
生产者线程将生产的产品送入缓冲区,消费者线程则从中取出产品。
缓冲区有N个,是一个环形的缓冲池。
*/
#include <stdio.h>
#include <pthread.h>
#define BUFFER_SIZE 16
struct prodcons
{
int buffer[BUFFER_SIZE];/*实际存放数据的数组*/
pthread_mutex_t lock;/*互斥体lock,用于对缓冲区的互斥操作*/
int readpos,writepos; /*读写指针*/
pthread_cond_t notempty;/*缓冲区非空的条件变量*/
pthread_cond_t notfull;/*缓冲区未满 的条件变量*/
};
/*初始化缓冲区*/
void pthread_init( struct prodcons *p)
{
pthread_mutex_init(&p->lock,NULL);
pthread_cond_init(&p->notempty,NULL);
pthread_cond_init(&p->notfull,NULL);
p->readpos = 0;
p->writepos = 0;
}
/*将产品放入缓冲区,这里是存入一个整数*/
void put(struct prodcons *p,int data)
{
pthread_mutex_lock(&p->lock);
/*等待缓冲区未满*/
if((p->writepos +1)%BUFFER_SIZE ==p->readpos)
{
pthread_cond_wait(&p->notfull,&p->lock);
}
p->buffer[p->writepos] =data;
p->writepos++;
if(p->writepos >= BUFFER_SIZE)
p->writepos = 0;
pthread_cond_signal(&p->notempty);
pthread_mutex_unlock(&p->lock);
}
/*从缓冲区取出整数*/
int get(struct prodcons *p)
{
int data;
pthread_mutex_lock(&p->lock);
/*等待缓冲区非空*/
if(p->writepos == p->readpos)
{
pthread_cond_wait(&p->notempty ,&p->lock);//非空就设置条件变量notempty
}
/*读书据,移动读指针*/
data = p->buffer[p->readpos];
p->readpos++;
if(p->readpos == BUFFER_SIZE)
p->readpos = 0;
/*设置缓冲区未满的条件变量*/
pthread_cond_signal(&p->notfull);
pthread_mutex_unlock(&p->lock);
return data;
}
/*测试:生产站线程将1 到1000的整数送入缓冲区,消费者线程从缓冲区中获取整数,两者都打印信息*/
#define OVER (-1)
struct prodcons buffer;
void *procer(void *data)
{
int n;
for( n=0;n<1000;n++)
{
printf("%d ------>\n",n);
put(&buffer,n);
}
put(&buffer,OVER);
return NULL;
}
void *consumer(void *data)
{
int d;
while(1)
{
d = get(&buffer);
if(d == OVER)
break;
else
printf("----->%d\n",d);
}
return NULL;
}
int main()
{
pthread_t th_p,th_c;
void *retval;
pthread_init(&buffer);
pthread_create(&th_p,NULL,procer,0);
pthread_create(&th_c,NULL,consumer,0);
/*等待两个线程结束*/
pthread_join(th_p, &retval);
pthread_join(th_c,&retval);
return 0;
}
⑦ C语言如何实现多线程同时运行
1、点击菜单栏的“Project”选项卡,下拉列表的最后一项“Project options...”是对当前工程的的属性进行设置的。
⑧ JAVA线程的机制有哪些
Java的线程机制 摘 要: 多线程机制是Java的重要技术,阐述了线程和进程的差别;Java中线程4个状态之间的转换;并结合例子说明了两种创建线程的方法。 线程是指程序中能顺序执行的一个序列。一个线程只有一个入口点� 但可能有几个出口点� 不过,每个时刻的执行点总是只有一个。线程是不能独立运行的程序,而只是某个整体程序内部的一个顺序执行流。 多线程是Java的一个重要特点。如果一个程序是单线程的,那么,任何时刻都只有一个执行点。这种单线程执行方法使系统运行效率低,而且,由于必须依靠中断来处理输入/输出。所以,当出现频繁输入/输出或者有优先级较低的中断请求时,实时性就变得很差。多线程系统可以避免这个缺点。所谓多线程,就是通过系统的调度使几个具有不同功能的程序流即线程同时并行地运行。 在单处理器计算机系统中,实际上是不可能使多个线程真正并行运行的,而要通过系统用极短的时间、极快的速度对多个线程进行切换,宏观上形成多个线程并发执行的效果。 1 线程和进程机制上的差别 线程和进程很相象,它们都是程序的一个顺序执行序列,但两者又有区别。进程是一个实体,每个进程有自己独立的状态,并有自己的专用数据段,创建进程时, 必须建立和复制其专用数据段,线程则互相共享数据段。同一个程序中的所有线程只有一个数据段, 所以, 创建线程时不必重新建立和复制数据段。由于数据段建立和复制这方面的差异,使线程的建立和线程间的切换速度大大优于进程,另一方面,线程又具备进程的大多数优点。 假设银行系统办理存款和取款手续,将帐本看成数据段。如果按进程这种机制,那么,当储户去存/取款时,银行应先把帐本复制一遍,为储户建立一个独立的帐本再结算。如果按线程机制, 那么,银行里所有的出纳员都用同一个帐本,储户来办存/取款时,也从这个帐本直接结算。用线程机制省去了数据段复制这一步显然是线程独具的特点。 由于多个线程共享一个数据段,所以,也出现了数据访问过程的互斥和同步问题,这使系统管理功能变得相对复杂。 总的来说,一个多线程系统在提高系统的输入/输出速度、有效利用系统资源、改善计算机通信功能以及发挥多处理器硬件功能方面显示了很大优势。因此,一些最新的操作系统如Windows95、Windows98、Windows NT等都提供了对多线程的支持。但是,在多线程操作系统下设计多线程的程序仍然是一个比较复杂和困难的工作。由于需要解决对数据段的共享,所以,原则上应该从程序设计角度采用加锁和释放措施,稍有不慎,便会使系统产生管理上的混乱。 而Java从语言一级提供对多线程的支持,这样,可由语言和运行系统联合提供对共享数据段的管理功能和同步机制,使得多线程并行程序设计相对比较容易。 2 Java线程的生命周期 每个线程都是和生命周期相联系的,一个生命周期含有多个状态,这些状态间可以互相转化。 Java的线程的生命周期可以分为4个状态;创建(new)状态;可运行(runnable)状态;不执行(notrunnable)状态;消亡(dead)状态。 创建状态是指创建一个线程对应的对象的过程,Java系统中,些对象都是从Java.lang包内一个称为Thread的类用关键字new创建的。刚创建的线程不能执行,必须向系统进行注册、分配必要的资源后才能进入可运行状态,这个步骤是由start操作完成的,而处于可运行状态的线程也未必一定处于运行中,它有可能由于外部的I/O请求而处于不运行状态。进入消亡状态后,此线程就不再存在了。 一个线程创建之后,总是处于其生命周期的4个状态之一中,线程的状态表明此线程当前正在进行的活动,而线程的状态是可以通过程序来进行控制的,就是说,可以对线程进行操作来改变状态。 这些操作包括启动(start)、终止(stop)、睡眠(sleep)、挂起(suspend)、恢复(resume)、等待(wait)和通知(notify)。每一个操作都对应了一个方法� 这些方法是由软件包Java.lang提供的。通过各种操作,线程的4个状态之间可按图1所示进行转换。 2.1 创建(new)状态 如果创建了一个线程而没有启动它,那么,此线程就处于创建状态。比如,下述语句执行以后,使系统有了一个处于创建状态的线程myThread:� Thread myThread=new MyThreadClass(); 其中,MyThreadClass()是Thread的子类,而Thread是由Java系统的Java.lang软件包提供的。处于创建状态的线程还没有获得应有的资源,所以,这是一个空的线程,线程只有通过启动后,系统才会为它分配资源。对处于创建状态的线程可以进行两种操作: 一是启动(start)操作,使其进入可运行状态;二是终止(stop)操作,使其进入消亡状态。如果进入到消亡状态,那么,此后这个线程就不能进入其它状态,也就是说,它不复存在了。 start方法是对应启动操作的方法,其具体功能是为线程分配必要的系统资源,将线程设置为可运行状态,从而可以使系统调度这个线程。 2.2 可运行(runnable)状态 如果对一个处于创建状态的线程进行启动操作,则此线程便进入可运行状态。比如,用下列语句� myThread.start();� � 则使线程myThread进入可运行状态。上述语句实质上是调用了线程体即run()方法,注意,run()方法包含在myThread线程中,也就是先由java.lang包的Thread类将run()方法传递给子类MyThreadClass(),再通过创建线程由子类MyThreadClass,传递给线程myThread。 线程处于可运行状态只说明它具备了运行条件,但可运行状态并不一定是运行状态,因为在单处理器系统中运行多线程程序,实际上在一个时间点只有一个线程在运行,而系统中往往有多个线程同时处于可运行状态,系统通过快速切换和调度使所有可运行线程共享处理器,造成宏观上的多线程并发运行。可见,一个线程是否处于运行状, 除了必须处于可运行状态外,还取决于系统的调度。 在可运行状态可以进行多种操作,最通常的是从run()方法正常退出而使线程结束,进入消亡状态。 此, 还可以有如下操作� 挂起操作,通过调用suspend方法来实现; 睡眠操作,通过调用sleep方法来实现; 等待操作,通过调用wait方法来实现; 退让操作,通过调用yield方法来实现; 终止操作,通过调用stop方法来实现。 前面三种操作都会使一个处于可运行状态的线程进入不可运行状态。比如,仍以myThread线程为例,当其处于可运行状态后,再用如下语句� myThread.sleep (5000); 则调用sleep方法使myThread线程睡眠5s(5000ms)。这5s内,此线程不能被系统调度运行,只有过5s后,myThread线程才会醒来并自动回到可运行状态。 如果一个线程被执行挂起操作而转到不可运行状态,则必须通过调用恢复(resume)操作,才能使这个线程再回到可运行状态。 退让操作是使某个线程把CPU控制权提前转交给同级优先权的其他线程。 对可运行状态的线程也可以通过调用stop方法使其进入消亡状态。 2.3 不可运行(not runnable)状态 不可运行状态都是由可运行状态转变来的。一个处于可运行状态的线程,如果遇到挂起(suspend)操作、睡眠(sleep)操作或者等待(wait)操作,就会进入不可运行状态。 另外,如果一个线程是和I/O操作有关的,那么,在执行I/O指令时,由于外设速度远远低于处理器速度而使线程受到阻, 从而进入不可运行状态,只有外设完成输入/输出之后,才会自动回到可运行状态。线程进入不可运行状态后,还可以再回到可运行状态,通常有三种途径使其恢复到可运行状态。 一是自动恢复。通过睡眠(sleep)操作进入不可运行状态的线程会在过了指定睡眠时间以后自动恢复到可运行状态,由于I/O阻塞而进入不可运行状态的线程在外设完成I/O操作后,自动恢复到可运行状态。 二是用恢复(resume)方法使其恢复。如果一个线程由于挂起(suspend)操作而从可运行状态进入不可运行状态,那么,必须用恢复(resume)操作使其再恢复到可运行状态。 三是用通知(notify或notifyAll)方法使其恢复。如果一个处于可运行状态的线程由于等待(wait)操作而转入不可运行状态,那么,必须通过调用notify方法或notifyAll方法才能使其恢复到可运行状态,采用等待操作往往是由于线程需要等待某个条件变量,当获得此条件变量后,便可由notify或ontifyAll方法使线程恢复到可运行状态。 恢复到可运行状态的每一种途径都是有针对性的,不能交叉。比如,对由于阻塞而进入不可运行状态的线程采用恢复操作将是无效的。 在不可运行状态,也可由终止(stop)操作使其进入消亡状态。 2.4 消亡(dead)状态 一个线程可以由其他任何一个状态通过终止(stop)操作而进入消亡状态。 线程一旦进入消亡状态,那它就不再存在了,所以也不可能再转到其它状态。 通常,在一个应用程序运行时,如果通过其它外部命令终止当前应用程序,那么就会调用(stop)方法终止线程。但是,最正常、最常见的途径是由于线程在可运行状态正常完成自身的任务而″寿终正寝″,从而进入消亡状态,这个完成任务的动作是由run方法实现的。 3 Java线程的两种创建途径 一种途径是通过对Thread的继承来派生一个子类,再由此子类生成一个对象来实现线程的创建,这是比较简单直接的办法。Thread类包含在系统API提供的8个软件包之一Java.lang中,Thread类中包含了很多与线程有关的方, 其中,一个名为run的方法就是用来实现线程行为的。比如:� 1 import java.lang.*� //引用lang包 2 class Mango exteds Thread { 3 public void run() { 4 ...... 5 �} 6 �} 上述程序段中,第1行语句引用软件包lang,这样做是为了给编译器一个信息,从而使后面程序中有关lang包中的方法可直接用方法名,而不必带前缀“Java.lang”。第2行语句是从lang包Thread派生一个子类Mango, 而这个子类中提供了run方法的实现,这样,运行时,将由子类Mango 的 run方法置换父类Thread的run方法。 不过这一步还没有创建线, 必须由子类生成一个对象,并且进行启动操作,这样才能得到一个处于可运行状态的线程。生成对象其实就是完成线程的创建,而启动是对已创建的线程进行操作。具体语句如下:� Mango t=new Mango(); � t.start(); � 上面先用关键字new使线程进入创建状态,又调用start()方法使线程进入可运行状态。注意,start()方法是由Thread继承给子类Mango、然后又在生成对象时由对象t从类Mango得到的。 另一种途径是通过一个类去继承接口runnable来实现线程的创建� 而这个类必须提供runnable接口中定义的方法run()的实现。runnable是Java.lang包中的一个接口,在runnable接口中,只定义了一个抽象方法run()。所以,如用这种途径来创建线程,则应先由一个类连接接口runnable,并且提供run()方法的实现。比如,下面的程序段实现了与接口的连接。 1 public class xyz implements Runnable{ 2 int i; � 3 public voed run(){ 4 while (true){ � 5 System.out.println("Hello"+i++); 6 � } 7 � } 8 � } 然后再创建一个线程� runnable r=new xyz(); � Thread t=new Thread(r); 这种途径创建线程比第一种途径灵活。当一个类既需要继承一个父类又要由此创建一个线程时,由于Java不支持多重继承,这样,用第一种途径将行不通,因为,按此思路创建线程也是以继承的方法实现的。 于是,就需要一个类既继承Thread类,又继承另一个父类。但用接口方法却能实现这个目标。 4 线程的启动和终止 Thread的start()方法对应于启动操作,它完成两方面的功能:一方面是为线程分配必要的资源,使线程处于可运行状态,另一方面是调用线程的run()方法置换Thread的中run()方法或者置换runnable中的run()方法来运行线程。 使用start()方法的语句很简单,即: ThreadName.start(); 下面的程序段先创建并启动线程myThread, 然后使用sleep()方法让其睡眠20000ms即20s,使其处于不可运行状态,过20s后,线程又自动恢复到可运行状态。 Thread MyThread=new MyThreadClass(); MyThread.start();� � try{ � MyThread.sleep(20000); �} catch(InterrujptedException e){ }