多线程读写链表 pthread


#define HB_PACKET_FAIL -1
#define HB_PACKET_EMPTY 0
#define HB_PACKET_SUCCESS 1

struct hb_packet{
    char *data;
    int   size;
};

struct hb_packet_list{
    struct hb_packet packet;
    struct hb_packet_list *next;
};

struct hb_packet_queue{
    struct hb_packet_list *first_packet;
    struct hb_packet_list *last_packet;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    int count;
    unsigned int total_size;
    bool abort;
};


bool packet_queue_init(struct hb_packet_queue *q)
{
	memset(q, 0, sizeof(struct hb_packet_queue));
	if (pthread_mutex_init(&q->mutex, NULL) != 0)
		goto fail;
	if (pthread_cond_init(&q->cond, NULL) != 0)
		goto fail1;
	return true;
fail1:
	pthread_mutex_destroy(&q->mutex);
fail:
	return false;
}

void packet_queue_free(struct hb_packet_queue *q)
{	
	pthread_mutex_destroy(&q->mutex);
	pthread_cond_destroy(&q->cond);	
}


int packet_queue_put(struct hb_packet_queue *q, struct hb_packet *packet)
{
	struct hb_packet_list *new_packet;
	new_packet = (struct hb_packet_list *)malloc(sizeof(struct hb_packet_list));
	if (new_packet == NULL)
		return HB_PACKET_FAIL;
	new_packet->packet = *packet;
	new_packet->next = NULL;
	pthread_mutex_lock(&q->mutex);
	if (q->last_packet == NULL)
		q->first_packet = new_packet;
	else
		q->last_packet->next = new_packet;
	
	q->last_packet = new_packet;
	q->count++;
	q->total_size += new_packet->packet.size;
	pthread_cond_signal(&q->cond);
	pthread_mutex_unlock(&q->mutex);
	
	return HB_PACKET_SUCCESS;
}



int packet_queue_get(struct hb_packet_queue *q, struct hb_packet *packet,bool block)
{
	struct hb_packet_list *potential_packet;
	int return_status;
	pthread_mutex_lock(&q->mutex);
	while (true) {
		potential_packet = q->first_packet;
		if (potential_packet != NULL) {
			q->first_packet = potential_packet->next;
			if (q->first_packet == NULL)
				q->last_packet = NULL;
			q->count--;
			q->total_size -= potential_packet->packet.size;
			*packet = potential_packet->packet;
			free(potential_packet);
			return_status = HB_PACKET_SUCCESS;
			break;
			
		} else if (!block) {
			return_status = HB_PACKET_EMPTY;
			break;
		} else {
			pthread_cond_wait(&q->cond, &q->mutex);
			if (q->abort) {
				return_status = HB_PACKET_FAIL;
				break;
			}
		}
	}
	pthread_mutex_unlock(&q->mutex);
	return return_status;
}



DWORD WINAPI ThreadFun1(LPVOID pM)  
{  
    TRACE("×ÓÏ̵߳ÄÏß³ÌIDºÅΪ:%d\n×ÓÏß³ÌÊä³öHello World\n",GetCurrentThreadId());  
	
	hb_packet_queue *q = (hb_packet_queue *)pM;
	
	while(1)
	{
		struct hb_packet packet;
		int i = packet_queue_get(q,&packet,false);
		TRACE("get result =%d \n",i);
		if (i == 1)
		{
			TRACE("get result =%s \n",packet.data);
		}	
		Sleep(1111);
	}
	
    return 0;  
}  

DWORD WINAPI ThreadFun2(LPVOID pM)  
{  
    TRACE("×ÓÏ̵߳ÄÏß³ÌIDºÅΪ:%d\n×ÓÏß³ÌÊä³öHello World\n",GetCurrentThreadId()); 
	hb_packet_queue *q = (hb_packet_queue *)pM;
	while(1)
	{
		struct hb_packet packet;
		packet.data = "111111";
		packet.size = sizeof("111111");
		int i = packet_queue_put(q, &packet);
		TRACE("put result =%d \n",i);
		Sleep(1234);
	}
    return 0;  
}  

void CMy123444Dlg::OnCancel2() 
{
	// TODO: Add your control notification handler code here
	hb_packet_queue *queue = new hb_packet_queue;
	packet_queue_init(queue);
	HANDLE handle1 =CreateThread(NULL,0,ThreadFun1,queue,0,NULL);  
	HANDLE handle2 =CreateThread(NULL,0,ThreadFun2,queue,0,NULL);  
}

 

转载于:https://my.oschina.net/hanxiaodong/blog/1541982

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中有一个线程安全的链表实现,即`CopyOnWriteArrayList`。它是`List`接口的一个实现类,提供了线程安全的操作。 `CopyOnWriteArrayList`的特点是在进行操作时,会创建一个新的副本来进行操作,而原始数据不会被修改。这样可以保证读操作的并发性,因为读操作可以同时进行,而不需要加锁。只有在操作时会进行加锁,确保数据一致性。 由于每次操作都需要复制整个链表,所以在频繁进行操作时,性能会受到影响。因此,`CopyOnWriteArrayList`适用于读操作远远多于操作的场景。 以下是一个使用`CopyOnWriteArrayList`的示例代码: ```java import java.util.concurrent.CopyOnWriteArrayList; public class ThreadSafeLinkedList { private CopyOnWriteArrayList<Integer> list; public ThreadSafeLinkedList() { list = new CopyOnWriteArrayList<>(); } public void addElement(int element) { list.add(element); } public void removeElement(int element) { list.remove(Integer.valueOf(element)); } public int getSize() { return list.size(); } } ``` 在上面的示例中,我们使用`CopyOnWriteArrayList`来实现一个线程安全的链表。通过`addElement`方法向链表中添加元素,通过`removeElement`方法从链表中移除元素,通过`getSize`方法获取链表的大小。 需要注意的是,虽然`CopyOnWriteArrayList`提供了线程安全的操作,但并不意味着我们可以在所有情况下都使用它。在特定的业务场景下,需要根据实际需求选择适合的线程安全容器。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值