A. 关于ssl多线程参数的传递
void *sock_read(int *client) //short event,void *arg
{
char buf[1024];
memset(buf,0,1024);
int d=SSL_read(*client,buf,1024);//接收客户端的数据包
perror("SSL_read");
printf("d=%d\n",d);
·····
}
static void sock_accept(int server_socket,short event,void *arg)
{
struct event *ev=arg;
int new_server_socket;
////////////////////////////////////////
char sslbuff[MAXBUF +1];
SSL_CTX *ctx;
RSA *rsa;
X509 * client_cert;
char *str;
SSL_load_error_strings();//为打印调试信息做准备
SSL_library_init();//ssl初始化
OpenSSL_add_all_algorithms();//载入ssl算法
SSL_load_error_strings();//载入ssl错误信息
//;
while(1)
{
SSL *ssl;
struct sockaddr_in addr;
socklen_t len=sizeof(addr);
//由于此结构要长期使用,所以rev必须动态分配,否则离开此函数后会自动释放,导致segment fault
struct event *rev=(struct event *)malloc(sizeof(struct event));
new_server_socket=accept(server_socket,(struct sockaddr *)&addr,&len);
ssl=SSL_new(ctx);
SSL_set_fd(ssl,new_server_socket);
// 建立 SSL 连接
if (SSL_accept(ssl)==-1)
{
close(new_server_socket);
break;
}
client_cert = SSL_get_peer_certificate (ssl); //得到证书并打印信息
if (client_cert != NULL)
{
str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
if(str==NULL)
{
exit(1);
}
free (str);
str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0);
if(str==NULL)
{
exit(1);
}
free (str);
X509_free (client_cert);/*如不再需要,需将证书释放 */
}
else
{
printf ("client does not have certificate.\n");
}
pthread_t child_thread;
pthread_mutex_init(&mutex,NULL);//初始化
if((pthread_create(&child_thread,NULL,(void *)sock_read,(void *)&ssl))<0)//* talk_to_client
if(child_thread!=0)
{
pthread_join(child_thread,NULL);
}
//创建一个读事件,当有客户连接时,接收通知。
event_set(rev,new_server_socket,EV_READ,(void*)sock_read,rev);
event_add(rev,NULL);
event_add(ev,NULL);
printf("end sock_accept\n");
free(rev);
// 关闭 SSL 连接
SSL_shutdown(ssl);
SSL_free(ssl);
}
SSL_CTX_free (ctx);
close(new_server_socket);
}
程序中进行的是ssl accept之后参数的传递,但是在最上顶的。
B. 使用exe4j打包可运行的exe文件时如何配置jvm的参数,要求这个参数是可以根据需求改变的
可以将参数写入配置文件里,具体如下,在生成的exe目录下面在创建一个文件假设你的可运行文件为a.exe,那么你的jvm虚拟参数文件命名为a.exe.vmoptions。在这个文件写入你的参数配置就可以了,例如:最小内存设置为64m最大设置为256m,那么就在配置文件里写:
-Xms64m
-Xmx256m
注意每个参数都要进行换行
C. java里如何添加自定义的配置文件,jsP里去读取参数
java里可以再在resources里面新建一个XML file或者 file文件
XML file 会自动生成XML头,在下面加入内容就可以了,首先要有一个根节点,然后如果需要用到一些类,如:spring的一些类,就需要引入包,如:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.dist.*.controller" />
</beans >
其中<?xml ……就是头,<beans 是根节点,下面的<content:……是内容。
如果添加的事properties文件,格式如下:
# 连接池配置
pool.size = 2
pool.max = 50
然后jsp调用读取xml文件的方法去读取自重的内容就可以了。
D. C++多线程怎么实现
C++多线程也可以使用UNIX C的库函数,pthread_mutex_t,pthread_create,pthread_cond_t,pthread_detach,pthread_mutex_lock/unlock,等等。在使用多线程的时候,你需要先创建线程,使用pthread_create,你可以使主线程等待子线程使用pthread_join,也可以使线程分离,使用pthread_detach。线程使用中最大的问题就是同步问题,一般使用生产着消费者模型进行处理,使用条件变量pthread_cond_t,pthread_mutex,pthread_cond_wait来实现。别人说再多也是别人的,自己看书或者Google去吧。
E. 项目配置文件
Struts应用采用两个基于XML的配置文件来配置,分别是web.xml和struts-cofig.xml文件.web.xml文件是配置所有web应用的而struts-config.xml文件是struts专用的配置文件,事实上也是可以根据需要给这个配置文件起其他名称的.
Web应用的发布描述文件:
web应用发布描述文件可以在应用开着者,发布者和组装者之间传递配置信息,Web容器在启动的时候从该文件中读取配置信息,根据它来装载和配置web应用.文档类型定义DTD对XML文档的格式做了定义,DTD吧XML文档划分为元素,属性,实体每一种XML文档都有独自的DTD文件.可以从网上下载.<web-app>元素是web.xml的根元素,其他元素必须嵌入在<web-app>元素之内.要注意的是子元素也是有顺序的比如必须是首先<servlet>,然后<servlet-mapping>最后<taglib>.
为Struts应用配置Web.xml文件:
首先最重要的一步是配置ActionServlet,这个用<servlet>标签的servlet-name属性起一个名字叫action,然后用servlet-class属性指定ActionServlet的类.
然后用<servlet-mapping>标签的servlet-name属性指定action,在用url-pattern指定接收范围是*.do的请求.不管应用中包含了多少子应用,都只需要配置一个ActionServlet,类来出来应用中的不同的功能,其实者就是不必要的,因为Servlet本身就是多线程的,而且目前Struts只允许配置一个ActionServlet.声明ActionServlet的初始化参数:<servlet>的<init-param>子元素用来配置Servlet的初始化参数.param-name设置config参数名.param-value设置struts-config.xml的路径参数值.
配置欢迎使用清单:
如果客户访问Web的时候值是访问了WEB应用的根目录URL.没有具体的指定文件,Web会自动调用Web的欢迎文件.<welcome-file-list>元素来配置的.通过其中的<welcome-file>欢迎页面</welcome-file>来配置.
配置错误处理:
尽管Struts框架功能强大的错误处理机制,但是不能保证处理所有的错误或者异常.当错误发生时,如果框架不能处理这种错误,把错误抛弃给Web容器,在默认的情况下web容器会想客户端返回错误信息.如果想避免让客户看到原始的错误信息,可以在Web应用发布描述文件中配置<error-page>元素.通过<error-code>404来定义错误的类型.然后通过<location>要处理错误的JSP页面来对错误进行处理.还可以用<exception-type>来设置异常,然后通过<location>来处理异常的JSP页面来处理异常.
配置Struts标签库:
这个就和以前学到的JSP自定义标签类似,配置元素为<taglib>来配置.<taglib-uri>这个指定标签库的uri,类似起一个名称.<taglib-location>这个是标签库的位置也就是实际所在的路径.通过这样的方法引入一个标签库,然后在前台JSP页面就可以通过自己定义的URI来调用标签.
Struts配置文件:
struts-config.xml文件.
首先研讨一下org.apache.struts.config包,在struts应用启动的时候会把Struts配置文件信息读取到内存中,并把它们存放在config包中相关的JavaBean类的实例中.包中的每一个类都和struts配置文件中特定的配置元素对应,MoleConfig在Struts框架中扮演了十分重要的角色,它是整个config包的核心,在Struts运行时来存放整个应用的配置信息.如果有多个子应用都会有一个MoleConfig对象,它和Struts文件根元素的<struts-config>对应.根元素中包含<form-bean><action><forward>等元素.
<struts-config>元素:时Struts配置文件的根元素,和它对应的配置类MoleConfig类,<struts-config>元素有8个子元素.他们的DTD定义是data-sources?form-bean? global-exception?global-forwards?action-mapping?controller?message-resources?plug-in*在Struts配置文件中,必须按照DTD指定的先手顺序来配置<struts-config>元素的各个子元素,如果颠倒了这些子元素的顺序,会产生错误.
<data-sources>元素:用来配置应用所需要的数据源,数据源负责创建和特定的数据库的连接.许多数据源采用连接池的机制实现.以便提高数据库访问的性能.JAVA语言提供了javax.sql.DataSource接口,所有的数据源都必须实现这个接口.许多应用服务器和Web服务器都提供了数据源组件.很多数据库厂商也提供了数据源的实现.<data-sources>元素包含多个<data-source>子元素永远配置特定的数据源.他们可以包含多个<set-property>子元素用于设置数据源的各种属性.配置了数据源以后,就可以在Action类中访问数据源,在Action中定义了getDataSource(HttpRequest)方法,用于获取数据源对象的引用.然后可以利用DataSource对象调用getConnection获取一个连接对象对数据库进行操作.在配置文件中声明多个数据源的时候需要为每一个数据源分配唯一的Key值,通过这个来表示特定的数据源.获取特定的数据源的时候可以用dataSource = getDataSource(reqeust,”A”);
<form-beans>元素:用来配置多个ActionForm,包含一个或者N个<form-bean>子元素.每个<form-bean>元素都包含多个属性.className指定和<form-bean>匹配的类.name指定该ActionForm的唯一标识符,这个属性是必须的以后作为引用使用.type指定ActionForm类的完整类名,这个属性也是必须的.注意包名也要加上.<form-property>是指定动态的Form的元素,以后会深入了解.
<global-exception>元素:用于配置异常处理,元素可以包含一个或者多个<exception>元素,用来设置JAVA异常和异常处理类ExceptionHandler之间的映射.className指定和元素对应的配置类,默认的不用动.handler指定异常处理类默认是ExceptionHandler.key指定在本地资源文件中异常的消息Key,path指定当前异常发生的时候转发的路径.scope指定ActionMessages实例存放的范围.type指定需要处理异常类的名字,必须的.bundle指定Resource Bundle.
<global-forwards>元素:用来声明全局转发,元素可以有一个或者N个<forward>元素组成,用于把一个逻辑名映射到特定的URL,通过这种方法Action类或者JSP页面无需指定URL,只要指定逻辑名称就可以实现请求转发或者重定向.这样可以减少控制组件和视图的聚合.易于维护.className对应的配置类.contextRelative如果为true表示当path属性以/开头的时候,给出的是对应的上下文URL默认是false.name转发路径的逻辑名,必须写.path转发或者重定向的URL,必须写必须是以/开头.redirect设置为true的时候表示执行重定向操作,此项为false的时候,表示执行请求转发操作.重定向与请求转发的区别以后就是重定向是把请求生成应答给客户端然后在重新发送给定向的URL,浏览器地址栏会有显示.而转发就是直接把请求转发给本应用的另一个文件,不生成应答所以客户端IE没显示.
<action-mapping>元素:包含一个或者N个<action>元素,描述了从特定的请求路径到响应的Action的映射.在<action>元素中可以包含多个<exception>和<forward>子元素,他们分别配置局部异常处理和局部转发.attribute设置Action关联的ActionForm在request或者session范围内的key.就是在request或者session共享内的名称.className对应配置元素的类.默认的是ActionMapping.forward指定转发URL路径include指定包含URL路径.input指定包含表单的URL,当表单验证失败的时候发送的URL.name,指定和该Action关联的Form名字.该名字必须是在form-bean中定义过的,可写可不写.path必须/开头的方位Action的路径.parameter指定Action配置参数.在Action的execute()方法中可以调用ActionMapping的getParameter()方法来读取匹配的参数.roles指定允许调用该Action的安全角色,多个角色之间逗号格开.scope指定Form的存在范围.默认是session.tyep指定Action的完整类名.unknown如果是true表示可以处理用户发出的所有的无效的ActionURL默认是false.validate指定是否调用ActionForm的validate方法.
<controller>元素:用于配置ActionServlet.buffreSize指定上载文件的输入缓冲大小.该属性为可选默认4096.className指定元素对应的配置类,ControllerConfig.然后是contentType指定响应结果内容类型和字符编码,该属性为可选,默认是text/html如果在Action或者JSP网页也设置了类型内容,会覆盖这个.locale指定是否把Locale对象保存到当前用户的session中默认false.tempDir指定处理文件上载的临时工作目录.nochache如果是true在响应结果中加入特定的头参数.
<message-resources>元素:用来配置Resource Bundle.用于存放本地文本消息文件.className元素对应的配置类.MessageResourcesConfig.factory指定消息的工厂类.key指定文件存放的Servlet对象中采用的属性Key.null指定如何处理未知消息.parameter指定消息的文件名.
<plug-in>元素:用于配置Struts插件.
配置多应用模块:所有的子应用都可以共享同一个ActionServlet实例,但是每个子应用都有单独的配置文件.把应用划分为多个子应用模块.首先为每个应用创建单独的Struts配置文件,在web.xml的ActionServlet配置代码中添加几个子应用信息.采用元素来实现应用之间的切换.
Digester组件:是一个Apache的另一个开源代码项目.当Struts被初始化的时候,首先会读取并解析配置文件,框架采用Digester组件来且西配置文件.然后创建config包中的对象.者对象用于存放配置信息.
其实配置文件不难,只要都理其中的原理就OK了.真正实际的项目开发中,采用的工具例如Eclipse系列,提供了相应的插件,在创建一个Struts工程的时候配置文件的标签都是自动生成的,而我们只需要往里面填写属性就OK了.
F. 按键精灵多线程
一看就知道不是新手了!
第一个问题:两个线程中的delay都是单独进行的,不会相互影响
第二个问题:应该不行,我测试了一下,当计时器进程结束后就执行再次运行了,但此时主线程还在运行,这样就有多个主线程同时执行了
第三个问题:多线程太乱,不如do...loop until datediff("",,)简洁,循环多没办法的,要不就用配置文件来判断进程情况,还有就是自己写函数或者插件吧
期待你补充问题
G. 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回你了~