线程间共享全局变量
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int var = 100;
void* tfn() {
var = 200;
printf("thread\n");
return NULL;
}
int main() {
printf("before thread var = %d\n", var);
pthread_t tid;
pthread_create(&tid, NULL, &tfn, NULL);
sleep(1);
printf("after thread var = %d\n", var);
return 0;
}
gcc thread.c -pthread -o mythread
![](https://img.haomeiwen.com/i13167756/4a204a75d54913ab.png)
pthread_exit 退出线程
#include <pthread.h>
void pthread_exit(void *retval);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void* tfn() {
printf("thread\n");
pthread_exit(NULL); // 退出当前线程
return NULL;
}
int main() {
pthread_t tid;
pthread_create(&tid, NULL, &tfn, NULL);
sleep(1);
return 0;
}
pthread_join
pthread_join,阻塞等待线程退出,获取线程退出状态。回收线程资源。
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
成功返回0,失败返回错误码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
struct Person{
int age;
char name[512];
};
void* tfn() {
printf("thread\n");
struct Person* person;
person = malloc(sizeof(struct Person));
bzero(person,sizeof(struct Person));
person->age = 22;
strcpy(person->name, "张三");
pthread_exit( (void *)person);
}
int main() {
pthread_t tid;
int ret = pthread_create(&tid, NULL, &tfn, NULL);
if (ret !=0)
{
perror("pthread_create error");
exit(1);
}
struct Person *retPerson;
ret = pthread_join(tid, (void **)&retPerson); // pthread_join回收资源,获取线程退出值
if (ret !=0)
{
perror("pthread_join error");
exit(1);
}
printf("age = %d, name = %s\n",retPerson->age, retPerson->name);
pthread_exit(NULL);
}
![](https://img.haomeiwen.com/i13167756/0e753e571aa1d9a6.png)
pthread_cancel
#include <pthread.h>
int pthread_cancel(pthread_t thread);
pthread_cancel用来杀死取消线程,注意,线程的取消并不是实时的,需要等待线程达到某个取消点。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
void* tfn() {
while (1)
{
printf("thread pid=%d, tid=%lu\n",getpid(),pthread_self());
sleep(1);
pthread_testcancel();//自己添加一个取消点
}
return (void *)NULL;
}
int main() {
pthread_t tid;
int ret = pthread_create(&tid, NULL, &tfn, NULL);
if (ret !=0)
{
perror("pthread_create error");
exit(1);
}
sleep(5);
pthread_cancel(tid);
while(1);
}
![](https://img.haomeiwen.com/i13167756/d58577a2505e42a3.png)
线程分离
线程的分离状态决定一个线程以什么样的方式来终止自己。
- 非分离状态:线程的默认属性是非分离状态,这种情况下,原有的线程等待创建的线程结束,只有当pthread_join返回时,创建的线程才算终止,才能释放自己占用的系统资源。
- 分离状态: 分离线程自己运行结束了,线程也就终止了。会自动释放系统资源。
pthread_detach线程分离
#include <pthread.h>
int pthread_detach(pthread_t thread);
pthread_detach实现线程分离,线程主动与主控线程断开关系,线程退出后,其退出状态不由其他线程获取,而是直接自己自动释放资源。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
void* tfn() {
printf("thread pid=%d, tid=%lu\n",getpid(),pthread_self());
return (void *)NULL;
}
int main() {
pthread_t tid;
int ret = pthread_create(&tid, NULL, &tfn, NULL);
if (ret !=0)
{
perror("pthread_create error");
exit(1);
}
pthread_detach(tid); // 设置线程分离,线程终止会自动清理pcb,无需回收
sleep(5);
}
使用线程属性设置分离线程
线程属性相关api
#include <pthread.h>
初始化线程属性
int pthread_attr_init(pthread_attr_t *attr);
销毁线程属性所占用的资源
int pthread_attr_destroy(pthread_attr_t *attr);
// 设置线程分离属性
PTHREAD_CREATE_DETACHED 分离线程
PTHREAD_CREATE_JOINABLE 非分离线程
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
// 获取线程分离属性
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
void* tfn() {
printf("thread pid=%d, tid=%lu\n",getpid(),pthread_self());
return (void *)NULL;
}
int main() {
pthread_t tid;
pthread_attr_t attr;
int ret = pthread_attr_init(&attr);
if (ret !=0)
{
fprintf(stderr, "pthread_attr_init error %s\n", strerror(ret));
exit(1);
}
ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ret = pthread_create(&tid, &attr, &tfn, NULL);
if (ret !=0)
{
perror("pthread_create error");
exit(1);
}
ret = pthread_attr_destroy(&attr);
if (ret !=0)
{
fprintf(stderr, "pthread_attr_destroy error %s\n", strerror(ret));
exit(1);
}
sleep(5);
}
线程屏蔽信号
#include <signal.h>
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include<errno.h>
#include <pthread.h>
#include <signal.h>
void sig_handler(int signo) {
printf("pthread id in the sig_handler:%lx\n ", pthread_self());
if (signo == SIGALRM)
{
printf("timeout...\n");
}
alarm(2);
}
void* th_fn(void *arg) {
if (signal(SIGALRM, sig_handler) == SIG_ERR)
{
perror("signal SIGALRM error...");
}
//在子线程中设置定时器,产生的SIGALRM信号发送给主线程
alarm(2);
int i;
for (i = 1; i < 100; i++)
{
printf("(%lx) i:%d\n",pthread_self(),i);
sleep(1);
}
return (void*)0;
}
int main() {
pthread_t th;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret;
ret = pthread_create(&th, &attr, th_fn, NULL);
if (ret !=0)
{
perror("pthread_create error");
}
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGALRM);
// 对主线程屏蔽SIGALRM信号
pthread_sigmask(SIG_SETMASK, &set, NULL);
while (1)
{
printf("control thread(%lu) is running\n", pthread_self());
sleep(10);
}
printf("control thread over\n");
return 0;
}
![](https://img.haomeiwen.com/i13167756/9ab7e029d777c733.png)
网友评论