02_线程,互斥锁的基础用法
Posted hello_zhao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了02_线程,互斥锁的基础用法相关的知识,希望对你有一定的参考价值。
NPTL
zhao@VM-0-8-ubuntu ~ % getconf GNU_LIBPTHREAD_VERSION [0]
NPTL 2.27
Linux内核不缺乏你进程和线程, 旨在用户层面上进行区分.
在linux下,线程是最小的执行单位;进程是最小的分配资源单位
线程基本用法
pthread_t
线程号,Linux 使用无符号长整数表示
pthread_self
获取线程号
pthread_create
创建一个线程
pthread_join
等待线程结束(此函数会阻塞),并回收线程资源.如果线程已经结束,那么该函数会立即返回。
pthread_detach
线程与当前进程分离,当被分离的线程结束之后,系统会自动回收它的资源。
pthread_cancel
杀死(取消)线程
pthread_equal
判断线程号 t1 和 t2 是否相等。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
//
////编译时需要指定连接线程库
////gcc pthread.c -pthread
//
void *run(void *arg) {
printf("新线程被调用了...\\n");
return NULL;
}
void *run2(void *arg) {
printf("线程2被调用了...%p\\n", arg);
return NULL;
}
void *run3(void *arg) {
printf("join线程被调用了...%p\\n", arg);
return NULL;
}
void *run4(void *arg) {
printf("detach线程被调用了...\\n");
return NULL;
}
void *run5(void *arg) {
sleep(1);
printf("线程退出被调用了...\\n");
pthread_exit(NULL);
return NULL;
}
void *run6(void *arg) {
for (int i = 0; i < 8; i++) {
sleep(1);
printf("%d...\\n", i);
}
return NULL;
}
int main(){
pthread_t tid = 0;
//获取当前线程的线程号
tid = pthread_self();
printf("tid: %lu\\n",tid);
if(pthread_equal(tid,pthread_self())){
printf("两个线程ID相同\\n");
}else{
printf("两个线程ID不相同\\n");
}
//创建一个线程
pthread_t ptid = 0;
pthread_t ptid2 = 0;
int ret = pthread_create(&ptid, NULL ,run, NULL);
if(0!=ret){
printf("pthread_create failed....\\n");
return 1;
}
int ret2 = pthread_create(&ptid2,NULL,run2, (void*)0x3);
if(0!=ret2){
printf("pthread_create failed....\\n");
return 1;
}
printf("main thread ...tid: %lu\\n",pthread_self());
getchar();
getchar();
fflush(stdout);
//--------线程阻塞实例------------
void * retp = NULL;
pthread_t tid3 = -1;
int ret3 = -1;
ret3 = pthread_create(&tid3,NULL,run3,NULL);
if(0!= ret3){
}
//主线程阻塞直到ret3执行完
ret3 = pthread_join(tid3,&retp);
if(0!=ret3){
printf("pthread_join fail...\\n");
return 1;
}
printf("retp: %p\\n",retp);
//------线程分离-----------
pthread_t tid4 = -1;
int ret4 = -1;
ret4 = pthread_create(&tid4,NULL,run4,NULL);
ret4 = pthread_detach(tid4);
if(0!=ret4){
printf("pthread_detach fail...\\n");
return 1;
}else{
printf("pthread_detach success...\\n");
}
getchar();
getchar();
//------线程退出-----------
pthread_t tid5 = -1;
int ret5 = -1;
ret5 = pthread_create(&tid5,NULL,run5,NULL);
ret5 = pthread_join(tid5,NULL);
if(0!=ret5){
printf("pthread5 pthread_join fail...\\n");
return 1;
}else{
printf("pthread5 pthread_join success...\\n");
}
getchar();
getchar();
//------线程取消-----------
pthread_t tid6 = -1;
int ret6 = -1;
ret6 = pthread_create(&tid6,NULL,run6,NULL);
ret6 = pthread_detach(tid6);
if(0!=ret6){
printf("pthread6 pthread_detach fail...\\n");
return 1;
}else{
printf("pthread6 pthread_detach success...\\n");
}
sleep(3);
printf("主线程睡眠3秒后取消子线程\\n");
ret6 = pthread_cancel(tid6);
if (ret6 != 0) {
printf("pthread_cancel fail\\n");
fprintf(stderr, "%s", strerror(ret6));
}
getchar();
getchar();
printf("main thread exit\\n");
return 0;
}
互斥锁的基本用法
pthread_mutex_init
pthread_mutex_destroy
pthread_mutex_lock
pthread_mutex_unlock
#include <stdio.h>
#include<unistd.h>
#include <pthread.h>
pthread_mutex_t mutex;
void *fun1(void *arg) {
//加锁
pthread_mutex_lock(&mutex);
for (int i = \'a\'; i <= \'z\'; ++i) {
putchar(i);
fflush(stdout);
usleep(10000);
}
//解锁
pthread_mutex_unlock(&mutex);
return NULL;
}
void *fun2(void *arg) {
//加锁
pthread_mutex_lock(&mutex);
for (int i = \'A\'; i <= \'Z\'; ++i) {
putchar(i);
fflush(stdout);
usleep(10000);
}
//解锁
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
//初始化一个互斥锁
pthread_mutex_init(&mutex,NULL);
pthread_t t1;
pthread_t t2;
pthread_create(&t1, NULL, fun1, NULL);
pthread_create(&t2, NULL, fun2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
//销毁互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}
//加锁前的输出:aABbcCdDEefFgGhHiIJjKklLmMNnoOPpqQrRSsTtUuVvWwXxYyZz
//加锁后的输出:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
条件变量
pthread_cond_t
pthread_cond_init
初始化
pthread_cond_destroy
pthread_cond_wait
释放该线程已持有的互斥锁, 并阻塞. 直到其他线程调用pthread_cond_signal
或pthread_cond_breadcast
pthread_cond_signal
通知pthread_cond_wait
阻塞的线程解除阻塞. 可以重新竞争互斥锁pthread_mutex_t
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
//
////编译时需要指定连接线程库
////gcc pthread.c -pthread
//
pthread_mutex_t pmt;
pthread_cond_t pct;
typedef struct _node_t {
int data;
struct _node_t *next;
} node_t;
node_t *head = NULL;
void *producer(void *arg) {
while (1) {
pthread_mutex_lock(&pmt);
node_t *newNode = (node_t *) (malloc(sizeof(node_t)));
memset(newNode, 0, sizeof(node_t));
newNode->data = rand() % 100 + 1;
newNode->next = NULL;
printf("produce %d\\n", newNode->data);
newNode->next = head;
head = newNode;
pthread_cond_signal(&pct);
pthread_mutex_unlock(&pmt);
sleep(3);
}
pthread_exit(NULL);
return NULL;
}
void *consumer(void *arg) {
node_t *temp = NULL;
while (1) {
pthread_mutex_lock(&pmt);
if (NULL == head) {
printf("consume nothing\\n");
pthread_cond_wait(&pct, &pmt);
}
temp = head;
head = head->next;
printf("consume %d\\n", temp->data);
free(temp);
pthread_mutex_unlock(&pmt);
}
pthread_exit(NULL);
return NULL;
}
int main() {
pthread_mutex_init(&pmt, NULL);
pthread_cond_init(&pct, NULL);
pthread_t pt1;
pthread_t pt2;
pthread_create(&pt1, NULL, producer, NULL);
pthread_create(&pt2, NULL, consumer, NULL);
pthread_join(pt1, NULL);
pthread_join(pt2, NULL);
pthread_mutex_destroy(&pmt);
pthread_cond_destroy(&pct);
return 0;
}
C++线程的基本使用
#include <iostream>
#include <thread>
#include <mutex>
#include <stdlib.h>
#include <chrono>
using namespace std;
mutex g_mutex;
void Deposit(mutex &m, int &money) {
m.lock();
for (int i = 0; i < 10; ++i) {
money += 10;
}
m.unlock();
}
void WithDraw(mutex &m, int &money) {
m.lock();
for (int i = 0; i < 10; ++i) {
money--;
}
m.unlock();
}
int main() {
mutex m;
int money = 1000;
thread t1(Deposit, ref(m), ref(money));
thread t2(WithDraw, ref(m), ref(money));
t1.join();
t2.join();
cout << money << endl;
return 0;
}
以上是关于02_线程,互斥锁的基础用法的主要内容,如果未能解决你的问题,请参考以下文章