码迷,mamicode.com
首页 > 编程语言 > 详细

POSIX线程库复习

时间:2015-03-14 15:15:05      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:

创建一个新的线程

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

thread:返回线程ID

attr:设置线程的属性,attr为NULL表示使用默认属性。

start_toutine:是个函数地址,线程启动后要执行的函数

arg:传给线程启动函数的参数。

 

成功返回0,失败返回错误码;

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>

#define ERR_EXIT(m)     do {         perror(m);        exit(EXIT_FAILURE);    }while(0)

void* therad_routine(void *arg)
{
    int i;
    for (i = 0; i < 20; ++i)
    {
        /* code */
        printf("B");
        fflush(stdout);
    }
    return 0;
}


int main(int argc, const char *argv[])
{
    pthread_t tid;
    int ret;
    ret = pthread_create(&tid, NULL, therad_routine, NULL);
    if(ret != 0)
    {
        fprintf(stderr, "pthread_create:%s\n", strerror(ret));        exit(EXIT_FAILURE);
    }
    int i;
    for (i = 0; i < 20; ++i)
    {
        /* code */
        printf("A");
        fflush(stdout);
        usleep(20);
    }
    sleep(1);
    return 0;
}
当线程创建失败时, 错误信息会返回到errno中。

pthread同样也提供了线程内的而errno变量,一支持其他使用errno的代码,

对于pthreads函数的错误,简易通过返回值判定,因为赌气返回值要比赌气线程内的errno变量的开销更小。

 

打印结果

ABABABABABAB

可以看得出单核的情况下,主线程和线程之间是共享CPU时间片的。

它们是交替进行的。

 

ret = pthread_join(tid, NULL);
    if(ret != 0)
    {
        fprintf(stderr, "pthread_join:%s\n", strerror(ret));
        exit(EXIT_FAILURE);
    }

主线程利用pthread_join来回收线程资源。

 

相对于多进程下僵尸进程的概念,多线程中也会产生僵尸线程。

所以我们可以使用pthread_detach来分离一个线程,这样便不会产生僵尸线程。

 

下面利用线程函数实现一个简单的回射服务器练习一下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define ERR_EXIT(m)     do {         perror(m);        exit(EXIT_FAILURE);    }while(0)

void* thread_routine(void* arg)
{
    pthread_detach(pthread_self());
    int conn = (int)arg;
    echo_sev(conn);
    printf("exiting thread ....\n");
    return 0;
}


int main(int argc, const char *argv[])
{
    int listen = socket(PF_INET, SOCK_STREAM, 0);
    if(socket < 0 )
        ERR_EXIT("socket");
    struct sockaddr_in servraddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(5188);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    int on = 1;
    //设置端口复用
    if(setsocketopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &ON, sizeof(on)) <0)
        ERR_EXIT("setsocketopt");
    if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) <0)
        ERR_EXIT("bind");

    if(listen(listenfd, SOMAXCONN)<0)
        ERR_EXIT("listen");
    struct sockaddr_in peeraddr;
    socklen_t peerlen;
    int conn;
    while(1)
    {
        conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen);
        if(conn < 0)
            ERR_EXIT("accept");

        printf("ip = %s, port = %d\n", inet_ntoa(peeraddr.sin_addr, ntohs(peeraddr.sin_port)));
        pthread_t tid;
        int ret;
        ret = pthread_create(&tid, NULL, thread_routine, (void*)conn);
        if(ret != 0)
        {
            fprintf(stderr, "pthread_create:%s\n", strerrno(ret));
            exit(EXIT_FAILURE);
        }
    }

    
    return 0;
}

注意点就是,要将创建的线程进行detrach,来避免僵尸线程的产生。

POSIX线程库复习

标签:

原文地址:http://www.cnblogs.com/DLzhang/p/4337540.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!