利用多线程完成图片复制,主线程复制前一半,子线程复制后一半;
多线程翻转字符串与输出字符串
一个线程读文件,另一个线程将读取的内容输出到终端
三个线程打印ABC,每个线程打一个字符,且顺序不变
三个线程打印ABC,每个线程打一个字符,且顺序不变


注意:
Compile and link with -pthread.
编译的时候需要手动连接 -pthread库
gcc 1.c -pthread
功能:
创建一个线程;
原型:
#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
参数:
pthread_t *thread:用于存储创建成功的线程的id号,tid号;
pthread_attr_t *attr:线程的属性,一般填NULL;
可以通过 pthread_attr_init函数进行设置attr属性。可以设置为分离属性。
void *(*start_routine) (void *):函数指针,回调函数。该指针可以指向返回值是void*类型,参数列表是(void*)类型的函数。
该指针指向的函数,是新创建的线程的执行体.(线程要执行什么任务,就写在这个函数里面);
例如可以指向 void* func(void* arg){ };
void *arg:给回调函数传递的参数;
返回值:
成功,返回0;
失败,返回错误码,注意不是errno;
指针类型 *指针名;
int *pa;
void *(*start_routine) (void *):
int (*p)[4];
注意:
1. 我们将从main函数进来的线程称之为主线程,新创建的线程称之为分支线程,或者子线程
2. 主线程和分支线程之间根据时间片轮询机制调度。主线程和分支线程谁先运行不确定。
3. 主线程退出后,会导致进程退出,从而在该进程下的其他分支线程会强制结束;
4. 分支线程退出,不会影响进程运行,所以不会导致其他线程退出。



功能:
退出线程;
原型:
#include
void pthread_exit(void *retval);
参数:
void *retval:该参数可以传递线程退出状态值,传递的参数会被pthread_join函数接收;
若不想传递,则参数填NULL;
线程退出后,会有类似僵尸线程的状态,需要使用pthread_join函数回收.
功能:
阻塞函数,阻塞等待指定的分支线程退出。
接收指定分支线程的退出状态值。
回收指定分支线程的资源。
原型:
#include
int pthread_join(pthread_t thread, void **retval);
参数:
pthread_t thread:指定要回收哪个分支线程,填对应的tid号;
void **retval:若该参数不为空,则pthread_join函数会将目标线程传递的退出状态值拷贝到该二级指针指向的一级指针空间内。
若不想接收,填NULL;
返回值:
成功,返回0;
失败,返回错误码(error number),注意不是errno,所以不能用perror函数
如:
pthread_join(tid, NULL);


功能:
分离线程,线程退出后资源自动被回收; 此时调用pthread_join函数操作同一个tid线程,pthread_join函数不阻塞
原型:
#include
int pthread_detach(pthread_t thread);
参数:
pthread_t thread:指定要分离的线程的tid号;
返回值:
成功,返回0;
失败,返回错误码,注意不是errno;

功能:
请求指定线程退出; 请求成功,对方线程不一定退出
原型:
#include
int pthread_cancel(pthread_t thread);
参数:
pthread_t thread:指定要请求哪个线程退出;
返回值:
成功,返回0;
失败,返回错误编号,即非0,没说更新errno,所以不能用perror打印;
功能:
创建并从初始化一个互斥锁;
原型:
#include
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
参数:
pthread_mutex_t *mutex:存储申请后的互斥锁;
pthread_mutexattr_t
*mutexattr:设置锁的属性,一般填NULL,代表用于线程;
该参数可以设置互斥锁是用于线程还是用于进程。
返回值:
永远返回0;
功能:
对互斥锁进行上锁,若有其他线程占用互斥锁,该函数会阻塞;
原型:
#include
int pthread_mutex_lock(pthread_mutex_t *mutex);
参数:
pthread_mutex_t *mutex;
返回值:
成功,返回0;
失败,返回非0,没有说更新errno,所以不要用perror打印错误。
功能:
解开互斥锁;
原型:
#include
int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数:
pthread_mutex_t *mutex;
返回值:
成功,返回0;
失败,返回非0,没有说更新errno,所以不要用perror打印错误。
功能:
销毁互斥锁
原型:
#include
int pthread_mutex_destroy(pthread_mutex_t *mutex);
参数:
pthread_mutex_t *mutex;
返回值:
成功,返回0;
失败,返回非0,没有说更新errno,所以不要用perror打印错误。
功能:
创建并初始化条件变量;
会在内核中创建一个cond_wait队列,mutex_wait队列,
原型:
#include
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
参数:
pthread_cond_t *cond:存储申请后的条件变量;
pthread_condattr_t
*condattr:设置条件变量的属性,一般填NULL,代表用于线程;
该参数可以设置条件变量是用于线程还是用于进程。
返回值:
成功,返回0;
失败,返回非0,没有说更新errno,所以不要用perror打印错误。
功能:
让线程进入休眠阶段,并设置一个条件变量,等待被唤醒.
当线程睡在cond上的时候,会将线程放入cond_wait队列中
在执行pthread_cond_wait函数之前,当前线程必须拥有锁资源(man手册原话)
原型:
#include
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
参数:
pthread_cond_t *cond:指定唤醒条件,我们一般成该线程睡在该条件变量上;
pthread_mutex_t *mutex:指定要解开的互斥锁,若不解开,该锁会变成死锁.
返回值:
成功,返回0;
失败,返回非0,没有说更新errno,所以不要用perror打印错误。
函数步骤:

功能:
通过指定的条件变量,唤醒指定的线程;
原型:
#include
int pthread_cond_signal(pthread_cond_t *cond);
参数:
pthread_cond_t *cond:指定要唤醒哪个条件变量上的线程;
返回值:
成功,返回0;
失败,返回非0,没有说更新errno,所以不要用perror打印错误。
功能:
销毁条件变量;
原型:
#include
int pthread_cond_destroy(pthread_cond_t *cond);
参数:
pthread_cond_t *cond:指定要销毁哪个条件变量上的线程;
返回值:
成功,返回0;
失败,返回非0,没有说更新errno,所以不要用perror打印错误。
功能:
创建并初始化信号量;
原型:
#include
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:
sem_t *sem:存储创建并初始化后的信号量;
int pshared:共享标识;
0,用于同一个进程下的线程.
非0,用于进程之间;
unsigned int value:指定信号量中的初始值;
返回值:
成功,返回0;
失败,返回-1,更新errno;
功能:
申请信号量。
若信号量的值大于0,则申请信号量成功,此时信号量的值会-1,且能够成功进入临界区,执行临界区代码。
若信号量的值等于0,则申请信号量失败,当前线程进入休眠阶段,等待信号量的值大于0.
原型:
#include
int sem_wait(sem_t *sem);
参数:
sem_t *sem:init创建的信号量
返回值:
成功返回0,信号量减少1
失败返回-1,更新errno,信号量的值不变
功能:
释放信号量; 不会阻塞
原型:
#include
int sem_post(sem_t *sem);
参数:
sem_t *sem:init创建的信号量
返回值:
成功返回0,信号量加1
失败返回-1,更新errno,信号量值不变
功能:
销毁信号量
原型:
#include
int sem_destroy(sem_t *sem);
参数:
sem_t *sem:需要销毁的信号量
返回值:
成功返回0,信号量加1
失败返回-1,更新errno
