1. 无题
在linux 2.6以前, pthread线程库对应的实现是一个名叫linuxthreads的lib. linuxthreads利用前面提到的轻量级进程来实现线程。
到了linux 2.6, glibc中有了一种新的pthread线程库NPTL(Native POSIX Threading Library). NPTL实现了前面提到的POSIX的全部5点要求. 但是, 实际上, 与其说是NPTL实现了, 不如说是linux内核实现了.在linux 2.6中, 内核有了线程组的概念, task_struct结构中增加了一个tgid(thread group id)字段. 如果这个task是一个”主线程”, 则它的tgid等于pid, 否则tgid等于进程的pid(即主线程的pid),此外,每个线程有自己的pid。
2. API
#include <pthread.h>
int pthread_create(pthread_t *thread, pthread_attr_t * attr, void*(*start_routine)(void *), void *arg);
void pthread_exit(void *retval);
int pthread_join(pthread_t thread, void **thread_return)
例程:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
void *thread_function(void *arg);
char message[] = "hello word";
int main(int argc, char *argv[])
{
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, (void*)message);
if(res != 0){
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
printf("Waiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if(res != 0){
perror("Thread jion failed\n");
exit(EXIT_FAILURE);
}
printf("Thead joined, it return %s\n", (char*)thread_result);
printf("Message now is %s\n", message);
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg)
{
printf("thread_fuction is runing...argument is %s\n", (char*)arg);
sleep(5);
strcpy(message, "Bye!");
pthread_exit("Thank you for your cup tiome\n");
}
3. 线程同步–信号量
#include <semaphore.h>
int sem_int(sem_t *sem, int pshared, unsigned int value); // pshare 用于进程间共享, linux 暂不支持,值为0
int sem_wait(sem_t *sem);
int sem_post(sem_t * sem);
int sem_destroy((sem_t *sem);
post 操作给信号量加 1,wait 操作给信号量减 1 但是他会阻塞知道信号量有个非零值才做减法操作。
sem_trywait
是sem_wait
的非阻塞版本。
例程:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem;
void *thread_function(void *arg);
#define WORK_SIZE 1024
char work_area[WORK_SIZE];
int main(int argc, char *argv[])
{
int res;
pthread_t a_thread;
void *thread_result;
res = sem_init(&sem, 0, 0);
if(res != 0){
perror("Init semaphore failed\n");
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if(res != 0){
perror("Create thread failed\n");
exit(EXIT_FAILURE);
}
printf("Input some text. Enter 'end' to finish..\n");
while(strncmp("end", work_area, 3) != 0){
fgets(work_area, WORK_SIZE, stdin);
sem_post(&sem);
}
printf("Waiting for the thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if(res != 0){
perror("thread join failed\n");
exit(EXIT_FAILURE);
}
printf("Thread joined\n");
sem_destroy(&sem);
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg){
sem_wait(&sem);
while(strncmp("end", work_area, 3) != 0){
printf("you input %d characters\n", strlen(work_area) - 1);
sem_wait(&sem);
}
pthread_exit(NULL);
}
在上面的例程中有一个问题,假设计算字符个数的线程运行速度比主线程慢(可以在线程中加入一段 sleep),那么久会出现字符还没被计算出来字符数组 work_area 的内容就被改变了,也就是说这时候的限号量大于 1 了。
4. 线程同步–互斥量
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
int phtread_mutex_lock(pthread_mutex_t *mutex);
int phtread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(phtread_mutex_t *mutex);
5.线程属性
#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
int pthread_attr_setdetachstate(pthread_attr_t * attr, int detachstate);
int pthread_attr_getdetachstate(phtread_attr_t *attr,, int *detachstate);
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);
int pthread_attr_setschedparam(pthread_attr_t * attr, const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t * attr, const struct sched_param *param);
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit);
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);
int pthread_attr_setstacksize(pthread_attr_t *attr, int size);
int pthread_attr_setstacksize(const pthread_attr_t *attr, int *size);
6. 取消线程
#include <.pthread.h>
int pthread_cancel(pthread_t thread);
#include <.pthread.h>
int pthread_setcancelstate(in state, int *oldstate);
PTHREAD_CANCEL_ENABLE
PTHREAD_CANCEL_DISABLE
#include <.pthread.h>
int pthread_stecanceltype(int state, int *oldstate);
PTHREAD_CANCEL_ASYNCHRONOUS
PTHREAD_CANCEL_DEFERRED
7. 没了
线程的知识很多,这里做个粗略的总结