为什么使用线程

  1. 并行parallelism的需要
  2. 避免程序因为低速的IO操作阻塞
  3. 尽管可以用多进程解决一些问题,但是线程可以共享一个内存地址空间,当需要贡献数据的时候线程的选择更自然

线程的问题

  1. 共享数据比较难操作
  2. 不可控制的执行计划
  3. 线程等待其他线程

线程Thread API

1.Thread Creation

#include <pthread.h>
       int
       pthread_create(      pthread_t *       thread,
                      const pthread_attr_t *  attr,
                            void *            (*start_routine)(void*),
                            void *            arg);

第一个参数 thread 是结构类型pthread_t 的指针,我们用它来和thread交互,所以需要把它传给pthread_create()来初始化它

第二个参数是是设置线程的属性

第三个线程要执行的function

第四个是第三个参数function的参数

代码


#include <pthread.h> 2
typedef struct __myarg_t {
	int a;
	int b;
} myarg_t;

void *mythread(void *arg) {
	myarg_t *m = (myarg_t *) arg;
	printf("%d %d\n", m->a, m->b);
	return NULL;
}

int
main(int argc, char *argv[]) {
	pthread_t p;
	int rc;
	
	myarg_t args;
	args.a = 10;
	args.b = 20;
	rc = pthread_create(&p, NULL, mythread, &args);
	//...
}

2.Thread Completion


typedef struct __myret_t {
    int x;
    int y;
} myret_t;


void *mythread(void *arg) {
    myarg_t *m = (myarg_t *) arg;
    printf("%d %d\n", m->a, m->b);
    myret_t *r = malloc(sizeof(myret_t));
    r->x = 1;
    r->y = 2;
    return (void *) r;
}

pthread_t p; //线程
myret_t *m; //线程返回结果
pthread_create(&p, NULL, mythread, &args);
pthread_join(p, (void **) &m);

3.Locks

POSIX线程库除了线程的创建和完成另一个最常用的函数系列就是locks 了

pthread_mutex_t lock; //声明一个锁
pthread_mutex_lock(&lock); //获得锁
x = x + 1; // 你认为的重要的业务代码部分
pthread_mutex_unlock(&lock);//释放锁

4.Condition Variables

POSIX线程库另外一个重要的部分就是condition variables **pthread_cond_t **

当多个线程之间需要交流信号的时候condition variables就非常有用

//让调用的线程sleep 等待其他线程唤醒(signal)它
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
//唤醒(signal)操作
int pthread_cond_signal(pthread_cond_t *cond);
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;
Pthread_mutex_lock(&lock);
//当ready==0的时候sleep
while (ready == 0)//ready 全局的变量
    Pthread_cond_wait(&cond, &lock);
Pthread_mutex_unlock(&lock);
pthread_mutex_lock(&lock);
//ready 等于1了,唤醒上面那个sleep的线程
ready = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);