对于州议员,我是一名不是CS本科生的学生,但我正在成为CS大师。所以我欢迎任何人愿意给予的任何帮助。
这样做的目的是在2-4之间创建N个线程,然后使用随机生成的小写字符数组,使它们大写。
这需要使用N个线程(执行时由命令行定义),使用pthread尽可能均匀地划分工作。
我想问的主要问题是,我是否避免了线程之间的竞争条件?
我也在努力理解在线程之间划分工作。据我所知(如果我错了,请纠正我),通常在执行期间随机选择线程功能。所以,我假设我需要做一些事情,在N个线程中动态划分数组并设置它,以便每个线程将执行数组相同大小的子部分的大写?
我知道在我的代码中我可能需要更好的其他差异,但我没有编写很长时间,只是在一个月前开始使用C / C ++。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <ctype.h>
//Global variable for threads
char randChars[60];
int j=0;
//Used to avoid race conditions
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
//Establish the threads
void* upperThread(void* argp)
{
while(randChars[j])
{
pthread_mutex_lock( &mutex1 );
putchar (toupper(randChars[j]));
j++;
pthread_mutex_unlock( &mutex1 );
}
return NULL;
}
int main(int argc, char **argv)
{
//Initializae variables and thread
int N,randNum,t;
long i;
pthread_t pth[N];
pthread_mutex_init(&mutex1, NULL);
char randChar = ' ';
//Check number of command inputs given
if(argc!=2)
{
fprintf(stderr,"usage: %s <enter a value for N>\n", argv[0]);
exit(0);
}
N = atoi(argv[1]);
//Checks command inputs for correct values
if(N<2||N>4){
printf("Please input a value between 2 and 4 for the number of threads.\n");
exit(0);
}
//Seed random to create a randomized value
srand(time(NULL));
printf("original lower case version:\n");
for (i=0; i<61; i++)
{
//Generate a random integer in lower alphabetical range
randNum = rand()%26;
randNum = randNum+97;
//Convert int to char and add to array
randChar = (char) randNum;
randChars[i] = randChar;
printf("%c", randChar);
}
//Create N threads
for (i=0; i<N; i++)
{
pthread_create(pth + i, NULL, upperThread, (void *)i);
}
printf("\n\nupper case version:\n");
//Join the threads
for(t=0; t < N; t++)
{
pthread_join(pth[t], NULL);
}
printf("\n");
pthread_exit(NULL);
return 0;
}
答案 0 :(得分:0)
您提供的示例不是一个好的多线程程序。原因是你的线程将一直等待持有锁的线程。这基本上使您的程序顺序。我会将您的upperThread
更改为
void* upperThread(void* argp){
int temp;
while(randChars[j]){
pthread_mutex_lock( &mutex1 );
temp = j;
j++;
pthread_mutex_unlock( &mutex1 );
putchar (toupper(randChars[temp]));
}
return NULL;
}
这样你的线程将等待一个持有锁的线程,直到它提取j
的值,增加它并释放锁,然后执行其余的操作。
一般规则是,只有在处理关键部分或关键数据时才必须获取锁定,在这种情况下,它是字符串的索引。阅读关键部分和比赛条件here