版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
多线程场景练习
场景1
有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:
A:1 2 3 4 1 2....
B:2 3 4 1 2 3....
C:3 4 1 2 3 4....
D:4 1 2 3 4 1....
代码实现:
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
#include <fstream>
using namespace std;
#define num_threads 4
pthread_cond_t ready = pthread_cond_initializer; // 线程ready
pthread_mutex_t mutex = pthread_mutex_initializer; // 条件变量ready的互斥锁
pthread_mutex_t c_mutex = pthread_mutex_initializer; // 为了保险,将sequence的访问也加上互斥锁
int state = 1; // 全局进程状态ready标记,1 表示线程1ready,2 表示线程2 ready,3 表示线程3 ready,4表示线程4 ready
int sequence[] = {1, 2, 3, 4}; // 初始的文件内容的写入顺序,后期每一次操作4个文件,便重新利用函数constructwritesequence() 构建一次sequence
string files[] = {
"filea.txt", "fileb.txt", "filec.txt", "filed.txt"
}; // 文件列表,后期不同的线程执行的时候,按照sequence去写入对应的文件
void writedata(int i);
void constructwritesequence(int sequence[], int filenum)
{
pthread_mutex_lock(&c_mutex);
int temp = sequence[0];;
int i = 1;
for (; i < filenum; i++)
{
sequence[i - 1] = sequence[i];
}
sequence[i - 1] = temp;
// cout << "next file process sequcece is: " << endl;
for (i = 0; i < filenum; i++)
{
cout << sequence[i] << " ";
}
cout <<endl;
pthread_mutex_unlock(&c_mutex);
}
void printer(int thread_id)
{
for (int i = 0; i < 4; i++)
{
if ((i + 1) == thread_id)
// cout << i;
writedata(i + 1);
}
}
int getindex(int i)
{
for (int index = 0; index < sizeof(sequence)/sizeof(int); index++)
{
if (i == sequence[index])
return index;
}
return 0x1234;
}
void writedata(int i)
{
pthread_mutex_lock(&c_mutex);
std::fstream afile;
int index = getindex(i);
if (index == 0x1234) {
cout << "index is out of bound" << endl;
return;
}
cout << "index is " << index << "i is " << i << endl;
afile.open(files[index].c_str(), std::ios::app | std::ios::out | std::ios::in);
afile << i << " ";
afile.close();
pthread_mutex_unlock(&c_mutex);
}
void* printer(void* arg)
{
int thread_id = *(int* )arg;
for(int index = 0; index < 10; index++) { // 演示 10 轮
pthread_mutex_lock(&mutex);
while (thread_id % 4 != state) {
pthread_cond_wait(&ready, &mutex); // 如果thread_id % 4 != state,则对应的线程需要继续等待ready条件满足
}
printer(thread_id);
state = (state + 1) % 4; // 修改对应的线程ready标记
if (thread_id == 4) {
constructwritesequence(sequence, 4);
}
pthread_mutex_unlock(&mutex);
pthread_cond_broadcast(&ready); // 某一个线程打印完毕后,设置state值,并通知其他所有线程,其他所有线程按照state的值,检查是否自己等待的ready条件是否满足
}
pthread_exit((void*) 1); // 每一个线程的返回值设置为1;
}
int main ()
{
int rc;
int i;
int thread_ids[] = {1, 2, 3, 4};
pthread_t threads[num_threads];
pthread_attr_t attr;
void *status;
// 初始化并设置线程为可连接的(joinable)
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, pthread_create_joinable);
// 创建4个线程
for( i=0; i < num_threads; i++ ){
rc = pthread_create(&threads[i], null, printer, (void*)(thread_ids + i));
if (rc){
cout << "create thread falied: " << rc << endl;
exit(-1);
}
}
// 删除属性,并等待其他线程
pthread_attr_destroy(&attr);
for( i=0; i < num_threads; i++ ){
rc = pthread_join(threads[i], &status);
if (rc){
cout << "error:unable to join," << rc << endl;
exit(-1);
}
cout << endl;
cout << "main: completed thread id :" << i ;
cout << " exiting with status :" << status << endl;
}
cout << "main: program exiting." << endl;
pthread_exit(null);
}