#include <pthread.h>
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);、
创建线程,其中:
thread:指向标志线程标识符的指针;
attr:用来设置线程的属性;
start_routine:线程的执行行数;
arg:传递给线程的唯一指针。
所有线程都有一个线程号,也就是Thread ID。其类型为pthread_t。通过调用pthread_self()函数可以获得自身的线程号。
#include <pthread.h>
int pthread_join(pthread_t thread, void **value_ptr);
pthread_join使一个线程等待另一个线程结束。
代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。当然可以设置线程的属性,子线程自己回收资源,而主线程退出不影响子线程继续执行。
pthread_t tid;线程pid
sigset_t set; 线程集结构体
int pthread_kill(pthread_t thread, int sig) 向线程thread 传递sig信号
#include <signal.h>
int sigwait(const sigset_t *restrict set, int *restrict sig);
在多线程中处理信号的原则却完全不同,它的基本原则是:将对信号的异步处理,转换成同步处理,也就是说用一个线程专门的来“同步等待”信号的到来,而其它的线程可以完全不被该信号中断/打断(interrupt)。这样就在相当程度上简化了在多线程环境中对信号的处理。
在多线程代码中,总是使用sigwait或者sigwaitinfo或者sigtimedwait等函数来处理信号;
而不是signal或者sigaction等函数。因为在一个线程中调用signal或者sigaction等函数会改变所以线程中;
信号处理函数。而不是仅仅改变调用signal/sigaction的那个线程的信号处理函数。
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
pthread_t ntid;定义线程ID
sigset_t set; 定义一个信号集
void *child_thread(void *p)
{
int signum;
while(1)
{
sigwait(&set, &signum); 监听信号的发生,把发送的信号保存在signum中
switch(signum)
{
case SIGUSR1:
printf("pthread running.\n");
continue;
case SIGUSR2:
printf("sleep 2s quit.\n");
sleep(1);
break;
default:
printf("no symbol..\n");
}
}
sigdelset(&set, SIGUSR2);
}
int main()
{
int retu;
char tmpc;
void *status;
sigemptyset(&set); 初始化set
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGUSR2);把信号加入信号集
retu = pthread_create(&ntid, NULL, child_thread, NULL);
if(retu < 0)
{
printf("create thread fail,rerurn.\n");
return -1;
}
while(1)
{
printf("Please input a char.\n");
scanf("%c",&tmpc);
switch(tmpc)
{
case 'a':
pthread_kill(ntid, SIGUSR1);发送信号
continue;
case 'q':
pthread_kill(ntid, SIGUSR2);
pthread_join(ntid,&status); 同步等待子线程退出
printf("finish\n");
break;
default:
printf("unknown symbol..\n");
}
}
return 0;
}