linux c/c++多线程程序的编写

第一次尝试编写linux下多线程程序,也是颇废一番周折。深知初学者对能快速的成功运行一段程序的渴望,所以本文专门用了“linux c/c++多线程程序的编写“这个醒目的标题,方便大家能即使从搜索引擎搜到本文,从而提升大家的信心。
首先先让代码进行起来再说为什么,见了效果再回过来头来看原因似乎会容易明白和理解一些。
测试代码如下:

#include[stdio.h]
#include[unistd.h]
#include[stdlib.h]
#include[pthread.h]
#include[string.h]
void *thread_function(void* arg);
char message[] = "Hello world!";
 
int main() {
    int res;
    pthread_t a_thread;
    void *thread_result;
 
    res = pthread_create(&a_thread, NULL, thread_function, (void*)message);
    if (0 != res) {
        perror("Thread creation faied");
        exit(EXIT_FAILURE);
    }
 
    printf("Waiting for thread to finish...\n");
    res = pthread_join(a_thread, &thread_result);
    if (0 != res) {
        perror("Thread join failed");
        exit(EXIT_FAILURE);
    }
    printf("Thread joined, it returned %s\n", (char*)thread_result);
    printf("Message is now %s\n",message);
    exit(EXIT_FAILURE);
}
void *thread_function(void* arg) {
    printf("thread_function is running. argument was %s\n",(char*)arg);
    sleep(3);
    strcpy(message,"bye!");
    pthread_exit("Thank you for the cpu time");
}

请将包含头文件的[替换成< ,]替换成>,代码高亮插件会认为尖括号是html标签,所以这里用中括号暂时替代。
编译:

hqlong@ubuntu:~/code/c$ gcc test.c -o test -lpthread

运行

hqlong@ubuntu:~/code/c$ ./test

结果

thread_function is running. argument was Hello world!
Waiting for thread to finish...
Thread joined, it returned Thank you for the cpu time
Message is now bye!

创建进程主要是通过pthread_create()这个函数来创建,函数的定义如下:

int pthread_create
(
	pthread_t *restrict tidp,
	const pthread_attr_t *restrict attr,
	void *(*start_rtn)(void),
	void *restrict arg
);

返回值:若是成功建立线程返回0,否则返回错误的编号
形式参数:
pthread_t *restrict tidp 要创建的线程的线程id指针
const pthread_attr_t *restrict attr 创建线程时的线程属性
void* (start_rtn)(void) 返回值是void类型的指针函数
vodi *restrict arg start_rtn的行参

注意上面还用到了pthread_join()这个函数,那么这个函数有什么用呢?接下来还是先看看它的原形定义:

int pthread_join
(
	pthread_t thread,
	void **value_ptr
);

各参数说明如下:
thread 等待退出线程的线程号
value_ptr 退出线程的返回值。
该函数的作用使得当前进程挂起,等待另一个进程返回才继续执行。也就是说当程序运行到这个地方时,程序会先停止,然后等线程id为thread的这个线程返回,然后程序才会断续执行。

在上面的例子中,如果把

  res = pthread_join(a_thread, &thread_result);
    if (0 != res) {
        perror("Thread join failed");
        exit(EXIT_FAILURE);
    }
    printf("Thread joined, it returned %s\n", (char*)thread_result);

注释掉,那么主程序根据不会等待线程返回,就退出,当然主进行退出了,他所创建的子进程也就会跟着退出,所以在上面的例子中,程序还在睡眠时,就被主进程强行退出了。

在上面例子进对源码进行编译时,加了-lpthread,如果不加-lprhead,会出现如下编译错误。

tmp/ccnPVTWo.o: In function `main':
mthread.c:(.text+0x30): undefined reference to `pthread_create'
mthread.c:(.text+0x6f): undefined reference to `pthread_join'
collect2: ld returned 1 exit status

thread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a。

更多细节请参考:
http://hi.baidu.com/wenlongren/blog/item/4615450f498006eaaa645759.html
http://hi.baidu.com/wenlongren/blog/item/998f04dd7e866de877c6383e.html
http://blog.sina.com.cn/s/blog_5dcf190f0100dbcm.html
http://hi.baidu.com/beisika/blog/item/8ced51cea7ac9c3eb600c8ea.html

机器人 2009-06-08 18:00 于 北京 阴
机器人 2009-06-09 10:48 于 北京 晴 更新

apache cgi程序的简单配置

首先添加虚拟主机

<virtualhost 127.0.0.1:50001>
</virtualhost>

这里新添加了50001端口来进行监听,所以还需要添加监听端口号

Listen 50001

要让程序能正常运行,还得通过配置ScriptAlias来允许服务器在指定的情况下,以CGI方式运行。

<virtualhost 127.0.0.1:50001>
ScriptAlias /cgi-bin/ /usr/local/ebserver/apache/cgi-bin/
</virtualhost>

所以上述的配置会告诉apache,所以以/cgi-bin/开头的资源都会被映射到/usr/local/webserver/apache/cgi-bin/目录下,并被认为是cgi程序。
然后重启服务器
在apache/cgi-bin/目录里有一些测试例子,我们可能用它来测试下,看看配置是否能正常运行。
比如说apache/cgi-bin/目录下有个test-cgi程序,源码如下:

#!/bin/sh
 
# disable filename globbing
set -f
 
echo "Content-type: text/plain; charset=iso-8859-1"
echo
 
echo CGI/1.0 test script report:
echo
 
echo argc is $#. argv is "$*".
echo
 
echo SERVER_SOFTWARE = $SERVER_SOFTWARE
echo SERVER_NAME = $SERVER_NAME
echo GATEWAY_INTERFACE = $GATEWAY_INTERFACE
echo SERVER_PROTOCOL = $SERVER_PROTOCOL
echo SERVER_PORT = $SERVER_PORT
echo REQUEST_METHOD = $REQUEST_METHOD
echo HTTP_ACCEPT = "$HTTP_ACCEPT"
echo PATH_INFO = "$PATH_INFO"
echo PATH_TRANSLATED = "$PATH_TRANSLATED"
echo SCRIPT_NAME = "$SCRIPT_NAME"
echo QUERY_STRING = "$QUERY_STRING"
echo REMOTE_HOST = $REMOTE_HOST
echo REMOTE_ADDR = $REMOTE_ADDR
echo REMOTE_USER = $REMOTE_USER
echo AUTH_TYPE = $AUTH_TYPE
echo CONTENT_TYPE = $CONTENT_TYPE
echo CONTENT_LENGTH = $CONTENT_LENGTH

然后在浏览器里输入http://127.0.0.1/cgi-bin/test-cgi
如果设置正确就能显示如下信息

CGI/1.0 test script report:
 
argc is 0. argv is .
 
SERVER_SOFTWARE = Apache/2.2.10 (Unix) PHP/5.2.8
SERVER_NAME = 127.0.0.1
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.1
SERVER_PORT = 50001
REQUEST_METHOD = GET
HTTP_ACCEPT = text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
PATH_INFO = 
PATH_TRANSLATED = 
SCRIPT_NAME = /cgi-bin/test-cgi
QUERY_STRING = 
REMOTE_HOST =
REMOTE_ADDR = 127.0.0.1
REMOTE_USER =
AUTH_TYPE =
CONTENT_TYPE =
CONTENT_LENGTH =

当然你也可以选择用其它语言来写一个cgi程序,其中apache提供了一个用pear写的例子。
下面是用C语言写的一个简单的例子。

#include <stdlib .h>
#include <stdio .h>
int main (int argc, char** argv) {
    char a[] = "-100";
    char b[] = "456";
    int c;
    c = atoi(a) + atoi(b);
    char *p;
    p = getenv("QUERY_STRING");
    printf("Content-type: text/html\n\n");
    printf("c=%d",c);
    printf("%s",p);
    return 0;
}
</stdio></stdlib>

实现功能为:打印打印a+b的值,如果有get参数,同时打印get参数
编译

hqlong@ubuntu:/usr/local/webserver/apache/cgi-bin$ gcc test.c -o test

这时我们可以通过http://127.0.0.1:50001/test来访问了。
如果通过http://127.0.0.1:50001/test?name=hqlong
我们的程序就会打印name=hqlong这个查询参数。
参考资料:http://doc.chinahtml.com/Manual/ApacheManual/howto/cgi.html
机器人 2009-05-05 17:52 于 北京

几步创建您的php扩展

下面以开发hello world这个简单的应用扩展为例,来说明开发的步骤,这个扩展提供一个hello_world()函数,该函数会返回一个”hello world”字符串,在php中的调用方式如下:

< ?php
    echo hello_world();
?>

首先进入php源码中的ext目录,php的所有扩展库的源码都放在这里。
然后创建hello目录,这个目录里就存放我们helloworld扩展的源码和相关文件.
Read more