多线程编程--线程休眠的方式

线程休眠/组赛


在线程不满足执行条件时,我们一般希望线程能休眠或者阻塞等待条件满足时再执行;或者,当我们创建新线程时,一般会让新线程阻塞一段时间,防止新线程生命周期过短,返回错误的值。

本文简单介绍了线程休眠的两种方式:

  1. sleep/usleep 的方式休眠;
  2. pthread_cond_wait()/pthread_cond_timedwaid();

sleep/usleep


使用 sleep()/usleep() 会让线程进入休眠,sleep 的单位时 s s susleep 的单位是 u s us us。很多人并不建议在多线程中使用 sleep()/usleep() 进行休眠操作。说是会休眠整个进程,但是我在测试中,并没有遇到休眠整个进程的问题。

以下用一个实例来说明如何使用 sleep/usleep 休眠线程。

以下代码中建立了两个线程:thread1 每隔 5 s 5s 5s 打印一次数据,thread2 每隔 1 s 1s 1s 遇到偶数打印一次数据。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>

void *thread1(void *param)
{
     int i;
     for(i = 0; i < 100; i++) {
         sleep(5); // 休眠 5 s
         if(i == 50) pthread_exit(NULL);
         printf("%s: %d: thread1: %d\n", __FILE__, __LINE__, i);
     }
}

void *thread2(void *param) 
{
    int i;
    for(i = 0; i < 100; i++) {
         usleep(1000000); // 休眠 1s
         printf("%s: %d: thread2: %d\n", __FILE__, __LINE__, i);
    }
}

int main()
{
    pthread_t pd1, pd2;
    int error;
	
    // 创建线程
    error = pthread_create(&pd1, NULL, thread1, NULL);
    if(error) {
         printf("%s: %d: 创建线程 thread1 失败: %d\n", __FILE__, __LINE__, error);
         return -1;
    }
	
    error = pthread_create(&pd2, NULL, thread2, NULL);
    if(error) {
         printf("%s: %d: 创建线程 thread2 失败: %d\n", __FILE__, __LINE__, error);
         return -1;
    }
	
     // 释放线程资源
    pthread_join(pd1, NULL);
    pthread_join(pd2, NULL);
	
    return 0;
}

结果:

pthread.c: 30: thread2: 0
pthread.c: 30: thread2: 1
pthread.c: 30: thread2: 2
pthread.c: 30: thread2: 3
pthread.c: 18: thread1: 0
pthread.c: 30: thread2: 4
pthread.c: 30: thread2: 5
pthread.c: 30: thread2: 6
pthread.c: 30: thread2: 7

# `pthread_cond_wait/pthread_cond_timedwait` ---- 大家都非常推荐使用 `pthread_cond_wait/pthread_cond_timedwait`。`pthread_cond_wait/pthread_cond_timedwait`是一系列动作的集合:**解锁**、**等待条件为true**、**加锁**。所以使用上述两个函数时要加锁。 - `pthread_cond_wait`:不机时条件等待; - `pthread_cond_timedwait`:计时条件等待;

通过 pthread_cond_wait/pthread_cond_timedwait 改写上述例子。

  • pthread1 每个 10 10 10s 打印一次,或者被信号触发才打印一次;
  • pthread2 每个 1 1 1s 遇到偶数打印一次,每 2 s 2s 2s 触发一次条件。
#pragma GCC diagnostic error "-std=c++11"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>

static pthread_cond_t cond; // 条件
static pthread_mutex_t mutex; // 锁

void *thread1(void *)
{
    int i;
    struct timeval now;
    struct timespec outtime;
	
    for(i = 0; i < 100; i++) {
        // 暂停10s
        gettimeofday(&now, NULL);
        outtime.tv_sec = now.tv_sec + 10;
        outtime.tv_nsec = now.tv_usec*1000;
        pthread_mutex_lock(&mutex); // 加锁
        pthread_cond_timedwait(&cond, &mutex, &outtime); // 动作集合:解锁、等待条件为 true、加锁
        //pthread_cond_wait(&cond, &mutex); 
        pthread_mutex_unlock(&mutex); // 解锁
  
        if(i == 50) pthread_exit(NULL);
        printf("%s: %d: thread1: %d\n", __FILE__, __LINE__, i);
    }
}

void *thread2(void *) 
{
    int i;
    for(i = 0; i < 100; i++) {
        usleep(1000000); // 暂停1s
        printf("%s: %d: thread2: %d\n", __FILE__, __LINE__, i);
        // 偶数时触发cond信号
        if (i % 2 == 0)	{
            pthread_mutex_lock(&mutex); // 加锁
            pthread_cond_signal(&cond); // 触发条件
            //pthread_cond_broadcast(&cond);
            pthread_mutex_unlock(&mutex); // 解锁
         }
    }
}

int main()
{
    pthread_t pd1, pd2;
    int error;
	
     // 初始化变量
     pthread_mutex_init(&mutex, NULL);
     pthread_cond_init(&cond, NULL);
	
     // 创建线程
     error = pthread_create(&pd1, NULL, thread1, NULL);
     if(error) {
         printf("%s: %d: 创建线程 thread1 失败: %d\n", __FILE__, __LINE__, error);
         return -1;
     }
	
     error = pthread_create(&pd2, NULL, thread2, NULL);
     if(error) {
         printf("%s: %d: 创建线程 thread2 失败: %d\n", __FILE__, __LINE__, error);
         return -1;
     }
	
     // 等待线程结束并回收线程资源
     pthread_join(pd1, NULL);
     pthread_join(pd2, NULL);
	
     return 0;
}

结果:

test.cpp: 42: thread2: 0
test.cpp: 30: thread1: 0
test.cpp: 42: thread2: 1
test.cpp: 42: thread2: 2
test.cpp: 30: thread1: 1
test.cpp: 42: thread2: 3
test.cpp: 42: thread2: 4
test.cpp: 30: thread1: 2
test.cpp: 42: thread2: 5
test.cpp: 42: thread2: 6
test.cpp: 30: thread1: 3
test.cpp: 42: thread2: 7
test.cpp: 42: thread2: 8
test.cpp: 30: thread1: 4
test.cpp: 42: thread2: 9
test.cpp: 42: thread2: 10
test.cpp: 30: thread1: 5
test.cpp: 42: thread2: 11
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Windows C多线程编程Demo可以通过使用Windows API来实现。以下是一个简单的例子: ```c #include <stdio.h> #include <windows.h> DWORD WINAPI ThreadFunc(LPVOID lpParam) { int thread_num = *((int*)lpParam); printf("Thread %d is running\n", thread_num); Sleep(1000); // 模拟线程执行的一些操作 printf("Thread %d is done\n", thread_num); return 0; } int main() { const int num_threads = 3; HANDLE threads[num_threads]; int thread_nums[num_threads]; for (int i = 0; i < num_threads; ++i) { thread_nums[i] = i; threads[i] = CreateThread(NULL, 0, ThreadFunc, &thread_nums[i], 0, NULL); if (threads[i] == NULL) { fprintf(stderr, "Error creating thread\n"); return 1; } } WaitForMultipleObjects(num_threads, threads, TRUE, INFINITE); // 等待所有线程执行完毕 for (int i = 0; i < num_threads; ++i) { CloseHandle(threads[i]); // 关闭线程句柄 } return 0; } ``` 上述代码创建了3个线程,并使用CreateThread函数创建了每个线程。每个线程执行相同的ThreadFunc函数,该函数简单地输出线程号,并模拟一些操作。主线程使用WaitForMultipleObjects函数等待所有线程执行完毕。最后,必须关闭每个线程句柄来释放资源。 这只是一个简单的多线程编程示例,在实际应用中,可能需要更复杂的线程同步和线程间通信机制,比如互斥量、信号量等。通过使用Windows API,我们可以实现更复杂和高效的多线程应用程序。 ### 回答2: Windows下的C语言多线程编程可以通过使用Windows API中提供的相关函数来实现。常用的函数包括`CreateThread`创建线程、`WaitForSingleObject`等待线程运行结束、`CloseHandle`关闭线程句柄等。 以下是一个简单的Windows C多线程编程的示例程序: ```c #include <stdio.h> #include <windows.h> DWORD WINAPI MyThreadFunc(LPVOID lpParam) { int i; for (i = 0; i < 5; i++) { printf("Thread is running: %d\n", i); Sleep(1000); // 线程休眠1秒 } return 0; } int main() { HANDLE hThread; DWORD dwThread; // 创建线程 hThread = CreateThread(NULL, 0, MyThreadFunc, NULL, 0, &dwThread); if (hThread == NULL) { printf("Failed to create thread.\n"); return 1; } printf("Main thread is running.\n"); // 等待线程结束 WaitForSingleObject(hThread, INFINITE); printf("Main thread is exiting.\n"); // 关闭线程句柄 CloseHandle(hThread); return 0; } ``` 该示例程序创建了一个新线程,新线程运行`MyThreadFunc`函数,该函数会打印5次当前运行次数,并休眠1秒。主线程输出一条信息后,使用`WaitForSingleObject`等待新线程运行结束,然后输出退出信息。 以上就是一个简单的Windows C多线程编程示例。在实际开发中,可以结合具体需求使用多线程来提升程序的并发性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值