Creating and deleting threads dynamically in eCos
来源:互联网 发布:欲知天下事,须读古今书 编辑:程序博客网 时间:2024/05/01 01:43
来源:
http://simonccheng.spaces.live.com/
下面的例子說明如何在eCos裡面動態產生thread.
Echo_Child 是要新產生的child thread,
紅色字為所需要用的的kernel API
Echo_Child_Cleaner可重要了,用來清除已經完成離開的child thread,
其中特別用來清除kernel scheduler的instance handle & structure, and stack
另外釋放child_info 的instance struct讓給下一個使用
程式裡用的是TCP port 6000的
能夠連接的connection 為 SIZE_OF_CHILD_INFO
#include <cyg/kernel/kapi.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <network.h>
#include <math.h>
#include <stdlib.h>
#include <network.h>
#define SIZE_OF_CHILD_INFO 10
#define MAX_SIZE_OF_STACK 4096
#define PRIORITY_SERVER 4
#define SERVER_PORT 6000
#define MAX_SIZE_OF_STACK 4096
#define PRIORITY_SERVER 4
#define SERVER_PORT 6000
typedef struct _tagCHILD_INFO_ {
cyg_tick_count_t delay;
cyg_handle_t handle;
cyg_thread thread;
int fd;
char stack[MAX_SIZE_OF_STACK];
} CHILD_INFO, *PCHILD_INFO;
char server_stack[MAX_SIZE_OF_STACK];
char cleaner_stack[MAX_SIZE_OF_STACK];
char cleaner_stack[MAX_SIZE_OF_STACK];
cyg_handle_t EchoServerHandle, EchoChildCleanerHandle;
cyg_thread_entry_t Echo_Server, Echo_Child_Cleaner, Echo_Child;
cyg_thread Echo_Server_Thread, Echo_Child_Cleaner_Thread;
cyg_thread_entry_t Echo_Server, Echo_Child_Cleaner, Echo_Child;
cyg_thread Echo_Server_Thread, Echo_Child_Cleaner_Thread;
cyg_handle_t cleaner_mbox_handle;
cyg_mbox cleaner_mbox;
cyg_mbox cleaner_mbox;
CHILD_INFO child_info[SIZE_OF_CHILD_INFO];
void Echo_Child_Cleaner(cyg_addrword_t data);
cyg_bool_t Tell_Cleaner(PCHILD_INFO pInfo);
cyg_bool_t Tell_Cleaner(PCHILD_INFO pInfo);
extern void cyg_test_exit(void);
void pexit(char *s)
{
perror(s);
cyg_test_exit();
}
void cyg_user_start(void)
{
cyg_thread_create(PRIORITY_SERVER, Echo_Child_Cleaner, (cyg_addrword_t) 0,
"Echo Child Cleaner", (void *) cleaner_stack, MAX_SIZE_OF_STACK,
&EchoChildCleanerHandle, &Echo_Child_Cleaner_Thread);
cyg_thread_resume(EchoChildCleanerHandle);
cyg_thread_create(PRIORITY_SERVER, Echo_Server, (cyg_addrword_t) 0,
"Echo Server", (void *) server_stack, MAX_SIZE_OF_STACK * 16,
&EchoServerHandle, &Echo_Server_Thread);
cyg_thread_resume(EchoServerHandle);
cyg_scheduler_start();
}
{
cyg_thread_create(PRIORITY_SERVER, Echo_Child_Cleaner, (cyg_addrword_t) 0,
"Echo Child Cleaner", (void *) cleaner_stack, MAX_SIZE_OF_STACK,
&EchoChildCleanerHandle, &Echo_Child_Cleaner_Thread);
cyg_thread_resume(EchoChildCleanerHandle);
cyg_thread_create(PRIORITY_SERVER, Echo_Server, (cyg_addrword_t) 0,
"Echo Server", (void *) server_stack, MAX_SIZE_OF_STACK * 16,
&EchoServerHandle, &Echo_Server_Thread);
cyg_thread_resume(EchoServerHandle);
cyg_scheduler_start();
}
void Echo_Server(cyg_addrword_t data)
{
int s, client, res;
socklen_t client_len;
struct sockaddr_in client_addr, local;
int one = 1;
PCHILD_INFO pChildInfo;
cyg_handle_t system_clockH;
cyg_resolution_t rtc_res;
int index;
{
int s, client, res;
socklen_t client_len;
struct sockaddr_in client_addr, local;
int one = 1;
PCHILD_INFO pChildInfo;
cyg_handle_t system_clockH;
cyg_resolution_t rtc_res;
int index;
init_all_network_interfaces();
if (!eth0_up) {
pexit("eth0 not up");
}
for (index=0;index<SIZE_OF_CHILD_INFO;index++) {
memset(&child_info[index], 0, sizeof(CHILD_INFO));
}
system_clockH = cyg_real_time_clock();
rtc_res = cyg_clock_get_resolution(system_clockH);
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
pexit("stream socket");
}
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
pexit("setsockopt SO_REUSEADDR");
}
if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one))) {
pexit("setsockopt SO_REUSEPORT");
}
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_len = sizeof(local);
local.sin_port = htons(SERVER_PORT);
local.sin_addr.s_addr = INADDR_ANY;
if((res = bind(s, (struct sockaddr *) &local, sizeof(local))) < 0) {
pexit("bind error");
}
listen(s, SOMAXCONN);
while (true) {
pexit("eth0 not up");
}
for (index=0;index<SIZE_OF_CHILD_INFO;index++) {
memset(&child_info[index], 0, sizeof(CHILD_INFO));
}
system_clockH = cyg_real_time_clock();
rtc_res = cyg_clock_get_resolution(system_clockH);
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
pexit("stream socket");
}
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
pexit("setsockopt SO_REUSEADDR");
}
if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one))) {
pexit("setsockopt SO_REUSEPORT");
}
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_len = sizeof(local);
local.sin_port = htons(SERVER_PORT);
local.sin_addr.s_addr = INADDR_ANY;
if((res = bind(s, (struct sockaddr *) &local, sizeof(local))) < 0) {
pexit("bind error");
}
listen(s, SOMAXCONN);
while (true) {
client_len = sizeof(client_addr);
if ((client = accept(s, (struct sockaddr *)&client_addr, &client_len)) < 0) {
pexit("accept");
}
for (index=0,pChildInfo=NULL;index<SIZE_OF_CHILD_INFO;index++) {
if (child_info[index].delay == 0) {
pChildInfo = &child_info[index];
pChildInfo->delay = (long long)((1000000000.0*rtc_res.divisor)
*((double)1)/((double)rtc_res.dividend)); //1 sec
break;
}
}
if (pChildInfo) {
pChildInfo->fd = client;
cyg_thread_create(PRIORITY_SERVER, Echo_Child, (cyg_addrword_t) pChildInfo,
"Echo Child", (void *) pChildInfo->stack, MAX_SIZE_OF_STACK,
&pChildInfo->handle, &pChildInfo->thread);
cyg_thread_resume(pChildInfo->handle);
} else {
perror("no instance available");
close(client);
}
}
close(s); // never happen here...
cyg_thread_exit();
}
if ((client = accept(s, (struct sockaddr *)&client_addr, &client_len)) < 0) {
pexit("accept");
}
for (index=0,pChildInfo=NULL;index<SIZE_OF_CHILD_INFO;index++) {
if (child_info[index].delay == 0) {
pChildInfo = &child_info[index];
pChildInfo->delay = (long long)((1000000000.0*rtc_res.divisor)
*((double)1)/((double)rtc_res.dividend)); //1 sec
break;
}
}
if (pChildInfo) {
pChildInfo->fd = client;
cyg_thread_create(PRIORITY_SERVER, Echo_Child, (cyg_addrword_t) pChildInfo,
"Echo Child", (void *) pChildInfo->stack, MAX_SIZE_OF_STACK,
&pChildInfo->handle, &pChildInfo->thread);
cyg_thread_resume(pChildInfo->handle);
} else {
perror("no instance available");
close(client);
}
}
close(s); // never happen here...
cyg_thread_exit();
}
void Echo_Child(cyg_addrword_t data)
{
PCHILD_INFO pChildInfo = (PCHILD_INFO)data;
char buf[1024];
int len;
fd_set in_fds;
struct timeval tv;
do {
len=0;
tv.tv_sec = 5; // 5 sec
tv.tv_usec = 0;
FD_ZERO(&in_fds);
FD_SET(pChildInfo->fd, &in_fds);
len = select(pChildInfo->fd+1, &in_fds, 0, 0, &tv);
if (len > 0) {
len = read(pChildInfo->fd, buf, sizeof(buf));
write(pChildInfo->fd, buf, len);
} else if (len < 0) {
pexit("select error");
len = 0;
}
} while (len);
{
PCHILD_INFO pChildInfo = (PCHILD_INFO)data;
char buf[1024];
int len;
fd_set in_fds;
struct timeval tv;
do {
len=0;
tv.tv_sec = 5; // 5 sec
tv.tv_usec = 0;
FD_ZERO(&in_fds);
FD_SET(pChildInfo->fd, &in_fds);
len = select(pChildInfo->fd+1, &in_fds, 0, 0, &tv);
if (len > 0) {
len = read(pChildInfo->fd, buf, sizeof(buf));
write(pChildInfo->fd, buf, len);
} else if (len < 0) {
pexit("select error");
len = 0;
}
} while (len);
if (pChildInfo->fd)
close(pChildInfo->fd);
Tell_Cleaner(pChildInfo);
cyg_thread_exit();
}
close(pChildInfo->fd);
Tell_Cleaner(pChildInfo);
cyg_thread_exit();
}
void Echo_Child_Cleaner(cyg_addrword_t data)
{
PCHILD_INFO pChildInfo;
cyg_mbox_create(&cleaner_mbox_handle, &cleaner_mbox);
while (cleaner_mbox_handle) {
pChildInfo = (PCHILD_INFO)cyg_mbox_get(cleaner_mbox_handle);
if (pChildInfo) {
if (pChildInfo->delay)
cyg_thread_delay(pChildInfo->delay);
cyg_thread_delete(pChildInfo->handle);
memset(pChildInfo, 0, sizeof(*pChildInfo));
pChildInfo = NULL;
}
}
cyg_thread_exit();
}
{
PCHILD_INFO pChildInfo;
cyg_mbox_create(&cleaner_mbox_handle, &cleaner_mbox);
while (cleaner_mbox_handle) {
pChildInfo = (PCHILD_INFO)cyg_mbox_get(cleaner_mbox_handle);
if (pChildInfo) {
if (pChildInfo->delay)
cyg_thread_delay(pChildInfo->delay);
cyg_thread_delete(pChildInfo->handle);
memset(pChildInfo, 0, sizeof(*pChildInfo));
pChildInfo = NULL;
}
}
cyg_thread_exit();
}
cyg_bool_t Tell_Cleaner(PCHILD_INFO pInfo)
{
if (cleaner_mbox_handle) {
return cyg_mbox_put(cleaner_mbox_handle, (void *)pInfo);
}
return 0;
}
- Creating and deleting threads dynamically in eCos
- Creating and Deleting Custom Menus in Visio
- Dynamically Creating Bound and Template Columns in GridView
- Creating threads in Java
- Dynamically creating bound and template columns in GridView using ASP.Net
- Creating Threads
- Creating Threads
- Creating Threads
- Dynamically creating keys/values in JavaScript associative array
- Dynamically creating a pie chart with ASP.NET and GDI+
- Processes and Threads in android
- WebLogic Stuck Threads: Creating, Understanding and Dealing with them
- Threads and Pipes in Console Apps
- Threads and Anonymous Classes in JAVA
- Managing Processes and Threads in Windows Forms
- Creating ASP.NET Controls Dynamically
- Creating DataGrid Templated Columns Dynamically -
- Creating Concurrency with Threads
- 正弦波
- Web Spider提取编码方法总结 (一)
- problem 1103
- 解决Struts里提交中文表单到ActionForm后的乱码问题。
- 中文乱码问题的解决方法 转载
- Creating and deleting threads dynamically in eCos
- 美人陷阱
- 常用的40个网站制作技巧
- 迷雾女子
- 关于 ASP.NET 中DropDownList 事件的用法
- 再生魔术之女
- FC下常用软件的安装配置
- 玫瑰与匕首
- 寻找事务代码对应的出口清单以及BADI