刚把《unix环境高级编程》看完,就迫不及待的写几篇
文章记录一下相关的知识点。我觉得总共就这个几个方面
线程、线程,io(系统io,c库函数,再来点通信io)。现在
先来一发通过接口控制线程的生命周期。


线程基本知识

线程同线程一样存在线程id,不过线程id和线程id不一样,线程id只有
在当前线程的上下文中有用,是附属于当前线程的。线程共享线程的空间没有
自己专享空间,所以需要解决的问题就是线程、 线程对一个临界区访问的同步
问题,这个就是我们常说的一个线程是否是线程安全的,如果是安全就不存在
这种同步问题,不安全的就是没有对临界区资源的访问做同步处理,主要就是
各种锁了。

线程创建

1
2
3
4
5
#include <pthread.h>
int pthread(pthread_t *restrict tipd,
const pthread_attr_t *restrict attr,
void *(*start_rtn)(void *), void *restrict arg);
返回值:若成功返回0;否则,返回错误编号

fork 子线程复制父线程线程空间但是共享正文部分,文件描述符也复制
就相当于执行了 dup 函数一样。

线程结束

正常结束

#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);

其中exit函数结束之前,会调用fflush函数,冲洗缓冲区 _Exit _exit 函数
不冲洗缓冲区直接结束线程。
main 函数中的return 相当于exit 函数,效果一样。
这些函数用在线程中会直接结束整个进程包括线程。

#include <pthread.h>
void pthread_exit(void *rval_ptr); /* rval_ptr 相当于结束状态 exit(stat)一样) */

调用者阻塞等待子线程结束

 #include <pthread.h>
 int pthread_join(pthread_t thread, void **rval_ptr);
                     返回值:若成功,返回0;否则,返回错误编号
跟wait_pid 函数功能一样,只是针对的是线程。

线程阻塞

#include <unistd.h>
int pause(void);
返回值:-1,errno 设置为 EINTR
只有执行了一个信号处理程序并从其返回时,pause才返回。在这种情况下   
pause返回-1, errno 设置为EINTR。

unsigned int alarm(unsigned int seconds);
返回值:0或以前设置的闹钟时间的余留秒数

sleep(int seconds) ;这个函数大家应该都很熟悉吧,那大家有木有自己
写过这个函数,或者知道这个函数是怎么实现的呢,其实我们可以通过alarm
这个函数定时,然后让线程阻塞(pause),时间到之后唤醒线程就可以达到sleep的效果
不过因为涉及到了信号的处理需要考虑竞度问题,因为alarm时间到了之后系统
会给你发出信号,信号处理完之后会继续执行pause之后的。下面是一个简单的例子

unsigned int sleep1(unsigned int seconds)
{
    if (signal(SIGALRM, sig_alrm) == SIG_ERR)
        return(seconds);
    alarm(seconds); /* start the timer */
    pause();        /* next caught sinal wakes us up */
    return(alarm(0)); /* turn off timer, return unslept time */ 
}