POSIX线程清理函数

#include <stdio.h>
#include <pthread.h>
#include <windows.h>	// Sleep

pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

struct Node
{
	int			number;
	struct Node	*next;
} *head = NULL;

// 清理函数
void cleanup_handler(void *node)
{
	printf("Cleanup handler of second thread.\n");
	free(node);
	pthread_mutex_unlock(&mtx);
}

void* thread_func(void *arg)
{
	struct Node *p = NULL;
	// 清理函数入栈,此demo只需一个清理函数
	pthread_cleanup_push(cleanup_handler, p);

	while (true)
	{
		pthread_mutex_lock(&mtx);
		if (head == NULL)
		{
			pthread_cond_wait(&cond, &mtx);
		}
		p = head;
		head = head->next;
		printf("Got %d from front of queue\n", p->number);
		free(p);
		pthread_mutex_unlock(&mtx);
	}
	/* 若从此处终止线程,则属于正常退出,无需清理。所以,只需将清理函数出栈。故而用
	参数零。若是从上面的“取消点”退出,则清理函数出栈时被调用:锁被打开,同时释放资源。*/
	pthread_cleanup_pop(0);
	return 0;
}

int main(int argc, char* argv[])
{
	pthread_t tid;
	pthread_create(&tid, NULL, thread_func, NULL);
	for (int i = 0; i < 10; i++)
	{
		struct Node* p = (Node *)malloc(sizeof(struct Node));
		p->number = i;

		// <!-- 对head操作属于临界区
		pthread_mutex_lock(&mtx);
		p->next = head;
		head = p;
		pthread_cond_signal(&cond);
		pthread_mutex_unlock(&mtx);
		// 所以要用互斥锁保护起来--!>

		Sleep(1);
	}
	printf("Main thread wants to cancel the 2nd thread.\n");

	/* 关于pthread_cancel,有一点额外的说明,它是从外部终止子线程,子线程会在
	最近的取消点,退出线程。而在我们的代码里,最近的取消点是pthread_cond_wait()了。*/
	pthread_cancel(tid);
	pthread_join(tid, NULL);
	printf("All done -- exiting\n");
	return 0;
}


清理函数的调用时机:

  • 调用pthread_exit()时,会调用清理函数;通过return返回的线程不会调用。
  • 被别的线程取消的时候,会调用。
  • pthread_cleanup_pop()参数为非零时,会调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值