Thread实验笔记
1、为什么用volatile?
C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier。这是 BS 在 “The C++ Programming Language” 对 volatile 修饰词的说明:
A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.
volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。例如:
volatile int i=10;
int a = i;
...
// 其他代码,并未明确告诉编译器,对 i 进行过操作
int b = i;
volatile 指出 i 是随时可能发生变化的,每次使用它的时候必须从 i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在 b 中。而优化做法是,由于编译器发现两次从 i读数据的代码之间的代码没有对 i 进行过操作,它会自动把上次读的数据放在 b 中。而不是重新从 i 里面读。这样以来,如果 i是一个寄存器变量或者表示一个端口数据就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问。
简而言之:volatile用于声明可能会由汇编代码修改值的变量
volatile int done;
__sync_fetch_and_add(&done, 1);
2、__sync_fetch_and_add
这是一个汇编语句,不会被编译!!
以count = 4为例,调用__sync_fetch_and_add(&count,1),之后,返回值是4,然后,count变成了5.
扩展资料
3、pthread.h
a. pthread_create: 用于创建新线程
int pthread_create(pthread_t * thread,
const pthread_attr_t * attr,
void * (*start_routine)(void *),
void * arg);
b.pthread_exit: 用于终止线程
void pthread_exit(void * retval);
// retval: 它是一个指向整型变量的指针,该整数储存线程终止的返回状态。读取的整型变量必须为全局变量,以便让任何等待加入该线程的线程可以读取其返回状态。
c. pthread_join: 用于等待线程终止
将子线程并入主线程,主线程会一直阻塞直至子线程执行结束(收到目标子线程的返回值)后,才回收子线程资源,解除阻塞状态,并继续执行主线程
int pthread_join(pthread_t th,
void **thread_return);
//th:当前线程等待加入的目标线程的线程id。
//thraad_return:指向th中提到的线程的退出状态存储位置的指针。
d.pthread_self: 用于获取当前线程id
pthread_t phread_self(void);
e.pthread_equal: 用于比较两个线程是否相同。如果两个线程相等则返回一个非零值,否则返回0
int pthread_equal(pthread_t t1,
pthread_t t2);
// t1:第一个线程id
// t2:第二个线程id
f.pthread_cancel: 用于向线程发送取消请求
int pthead_cancel(pthread_t thread);
// thread:用于指定发送Cancel信号的目标线程
例子
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void* func(void* arg)
{
// detach the current thread
// from the calling thread
pthread_detach(pthread_self());
printf("Inside the thread\n");
// exit the current thread
pthread_exit(NULL);
}
void fun()
{
pthread_t ptid;
// Creating a new thread
pthread_create(&ptid, NULL, &func, NULL);
printf("This line may be printed before thread terminates\n");
// The following line terminates
// the thread manually
// pthread_cancel(ptid);
// Compare the two threads created
if(pthread_equal(ptid, pthread_self())
printf("Threads are equal\n");
else
printf("Threads are not equal\n");
// Waiting for the created thread to terminate
pthread_join(ptid, NULL);
printf("This line will be printed after thread ends\n");
pthread_exit(NULL);
}
// Driver code
int main()
{
fun();
return 0;
}
Output
This line may be printed before thread terminates
Threads are not equal
Inside the thread
This line will be printed after thread ends
代码中有两个执行线程,主线程等待新创建的进程退出后才会打印输出的最后一行,如果我们想手动终止线程,可以使用pthread_cacnel完成。
注意:如果我们使用exit()而非pthread_exit()来结束线程,那么与执行
exit()的线程关联的所有线程都会终止,即使某些线程可能正在运行。
此部分源于:https://blog.youkuaiyun.com/Orange_pa/article/details/128476193
4、pthread_mutex_
pthread_mutex_t lock; // declare a lock
pthread_mutex_init(&lock, NULL); // initialize the lock
pthread_mutex_lock(&lock); // acquire lock
pthread_mutex_unlock(&lock); // release lock
-
pthread_mutex_t lock;
声明锁
-
pthread_mutex_init(&lock, NULL);
动态初始化
-
pthread_mutex_lock(&lock);
调用锁
当A线程获取了锁,B线程试图访问临界区域或该锁时会被堵塞