进程是系统分配资源的基本单位
,线程是进程的基本执行单元
,一个进程的所有任务都在线程中执行,进程想要执行任务,必须得有线程,进程至少要有一条线程,程序启动会默认开启一条线程,这条线程被称为主线程或UI线程
。开销要小
。高并发编程
。int pthread_create (
pthread_t *thread,
pthread_attr_t *attr,
void *(*start_routine)(void*),
void *arg
);
执行的是fork后面的代码
。执行对应的线程处理函数
。处理结果的相互影响
。不可重入的/线程不安全的
。示例:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
int my_global;
void* my_thread_handle(void* arg){
int val;
val = *((int*)arg);
printf("new thread begin,arg=%d\n",val);
my_global += val;
sleep(3);
pthread_exit(&my_global);
//下面一行不再执行
printf("new thread end\n");
}
int main(void){
pthread_t mythread;
int arg;
int ret;
void *thread_return;
arg = 100;
my_global = 1000;
printf("my_global=%d\n", my_global);
printf("ready create thread...\n");
ret = pthread_create(&mythread,0,my_thread_handle,&arg);
if (ret != 0) {
printf("create thread failed!\n");
exit(1);
}
printf("wait thread finished...\n");
ret = pthread_join(mythread,&thread_return);
if (ret != 0) {
printf("pthread_join failed!\n");
exit(1);
}
printf("wait thread end, return value is %d\n", *((int*)thread_return));
printf("my_global=%d\n", my_global);
printf("create thread finished!\n");
return 0;
}
最多只允许一个线程进入临界区
,则使用互斥量。多个线程之间的执行顺序满足某个约束
,则使用信号量。POSIX信号量
,而不是System V信号量。(用于进程之间的信号量)。示例:
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define BUFF_SIZE 80
char buff[BUFF_SIZE];
sem_t sem;
static void* str_thread_handle(void *arg)
{
while(1) {
//P(sem) -1
if (sem_wait(&sem) != 0) {
printf("sem_wait failed!\n");
exit(1);
}
printf("string is: %slen=%d\n", buff, strlen(buff));
if (strncmp(buff, "end", 3) == 0) {
break;
}
}
}
int main(void)
{
int ret;
pthread_t str_thread;
void *thread_return;
ret = sem_init(&sem, 0, 0);
if (ret != 0) {
printf("sem_init failed!\n");
exit(1);
}
ret = pthread_create(&str_thread, 0, str_thread_handle, 0);
if (ret != 0) {
printf("pthread_create failed!\n");
exit(1);
}
while (1) {
fgets(buff, sizeof(buff), stdin);
//V(sem) +1
if (sem_post(&sem) != 0) {
printf("sem_post failed!\n");
exit(1);
}
if (strncmp(buff, "end", 3) == 0) {
break;
}
}
ret = pthread_join(str_thread, &thread_return);
if (ret != 0) {
printf("pthread_join failed!\n");
exit(1);
}
ret = sem_destroy(&sem);
if (ret != 0) {
printf("sem_destroy failed!\n");
exit(1);
}
return 0;
}
效果等同于初始值为1的信号量。
示例:
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define BUFF_SIZE 80
int global_value = 1000;
pthread_mutex_t lock;
static void* str_thread_handle(void *arg)
{
int i = 0;
for (i=0; i<10; i++) {
pthread_mutex_lock(&lock);
if (global_value > 0) {
// work
sleep(1);
printf("soled ticket(%d) to ChildStation(%d)\n",
global_value, i+1);
}
global_value--;
pthread_mutex_unlock(&lock);
sleep(1);
}
}
int main(void)
{
int ret;
pthread_t str_thread;
void *thread_return;
int i;
ret = pthread_mutex_init(&lock, 0);
if (ret != 0) {
printf("pthread_mutex_init failed!\n");
exit(1);
}
ret = pthread_create(&str_thread, 0, str_thread_handle, 0);
if (ret != 0) {
printf("pthread_create failed!\n");
exit(1);
}
for (i=0; i<10; i++) {
pthread_mutex_lock(&lock);
if (global_value > 0) {
// work
sleep(1);
printf("soled ticket(%d) to MainStation(%d)\n",
global_value, i+1);
}
global_value--;
pthread_mutex_unlock(&lock);
sleep(1);
}
ret = pthread_join(str_thread, &thread_return);
if (ret != 0) {
printf("pthread_join failed!\n");
exit(1);
}
ret = pthread_mutex_destroy(&lock);
if (ret != 0) {
printf("pthread_mutex_destroy failed!\n");
exit(1);
}
return 0;
}
通常条件变量和互斥锁一起使用
。利用线程间共享的全局变量进行同步的一种机制
,主要包括两个动作:互斥锁的保护下
进行的。如果条件为假,一个线程自动阻塞(挂起),并释放等待状态改变的互斥锁。示例:
个人理解
,条件变量会为临界资源创建两道防线,第一道防线为进入等待唤醒前,第二道为进入临界区前。如下图示中
,注意
:#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex;//互斥量
pthread_cond_t cond;//条件变量
void *thread1(void *arg){
while (1) {
printf("thread1 is running\n");
pthread_mutex_lock(&mutex);//加锁
pthread_cond_wait(&cond, &mutex);//等待时挂起,然后开锁,被唤醒时,先加锁,然后再唤醒(即执行下方代码)。。
printf("thread1 applied the condition\n");
pthread_mutex_unlock(&mutex);//开锁
sleep(4);
}
}
void *thread2(void *arg){
while (1) {
printf("thread2 is running\n");
pthread_mutex_lock(&mutex);//加锁
pthread_cond_wait(&cond, &mutex);//等待时挂起,然后开锁,被唤醒时,先加锁,然后再唤醒(即执行下方代码)。
printf("thread2 applied the condition\n");
pthread_mutex_unlock(&mutex);//开锁
sleep(2);
}
}
int main(){
pthread_t thid1, thid2;
printf("condition variable study!\n");
pthread_mutex_init(&mutex, NULL);//互斥量初始化
pthread_cond_init(&cond, NULL);//条件变量初始化
pthread_create(&thid1, NULL, (void *)thread1, NULL);//线程1创建
pthread_create(&thid2, NULL, (void *)thread2, NULL);//线程2创建
do {
pthread_cond_signal(&cond);//唤醒一个等待线程
sleep(1);
} while (1);
return 0;
}